1. 程式人生 > >python機器學習——影象內容分析

python機器學習——影象內容分析

計算機視覺:

計算機視覺是一門研究如何使機器“看”的科學,更進一步的說,就是是指用攝影機和電腦代替人眼對目標進行識別、跟蹤和測量等機器視覺,並進一步做圖形處理,使電腦處理成為更適合人眼觀察或傳送給儀器檢測的影象。

計算機視覺包括多個級別的分析。在低階視覺分析領域,計算機視覺可以進行畫素處理,例如邊檢測,形態處理和光流。在中級和高階視覺分析領域,計算機視覺可以處理事物,例如物體識別,3D建模,運動分析以及其他方面的視覺資料。

計算機視覺與影象處理有什麼不同:

影象處理是在畫素級別對影象進行變換。影象處理系統的輸入和輸出都是影象,常用的影象處理有邊檢測,直方圖均衡化或影象壓縮。計算機視覺演算法大量依賴了影象處理演算法來執行任務,在計算機視覺領域,我們還處理更復雜的事情,例如在概念層級理解視覺資料,期望藉此幫助自己構建對影象物件更有意義的描述。計算機視覺系統的輸出是給定影象的3D場景的描述,這樣的描述可以是各種形式的,而這取決你的需要。

1.用OpenCV-python操作影象
載入並展示影象,裁剪,調整大小並將圖片儲存到輸出檔案中。
用到的圖片forest.jpg
這裡寫圖片描述

程式碼:

import sys
import cv2
import numpy as np

"""
指定輸入影象為檔案的第一個引數,並使用影象讀取函式來讀取引數
"""
# 載入並顯示影象 -- 'forest.jpg'
input_file = sys.argv[1]
img = cv2.imread(input_file)
#顯示輸入影象
cv2.imshow('Original', img)
"""
裁剪影象,提取輸入影象的高度和寬度,然後指定邊界
"""
# 裁剪影象 h, w = img.shape[:2] start_row, end_row = int(0.21*h), int(0.73*h) start_col, end_col= int(0.37*w), int(0.92*w) """ 用NumPy式的切分方式裁剪影象,並展示 """ img_cropped = img[start_row:end_row, start_col:end_col] cv2.imshow('Cropped', img_cropped) """ 將影象調整為原始影象大小的1.3倍,並展示 """ # 調整影象大小 scaling_factor = 1.3 img_scaled = cv2.resize(img, None
, fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR) cv2.imshow('Uniform resizing', img_scaled) img_scaled = cv2.resize(img, (250, 400), interpolation=cv2.INTER_AREA) cv2.imshow('Skewed resizing', img_scaled) # 儲存影象 output_file = input_file[:-4] + '_cropped.jpg' cv2.imwrite(output_file, img_cropped) cv2.waitKey()#waitKey函式保持顯示影象,直到按下鍵盤的任一個按鍵

在cmd中執行:python 檔名.py forest.jpg

輸入影象:
這裡寫圖片描述
裁剪後圖像:
這裡寫圖片描述
從兩個維度均勻調整大小後的影象:
這裡寫圖片描述
從一個維度調整大小後的影象:
這裡寫圖片描述

2.檢測邊
檢測邊是計算機視覺中最常用到的技術之一,常用在很多預處理過程中。
用到的圖片:chair.jpg
這裡寫圖片描述
程式碼:

import sys
import cv2
import numpy as np

# 載入輸入圖片 -- 'chair.jpg'
# 轉化為灰度圖
input_file = sys.argv[1]
img = cv2.imread(input_file, cv2.IMREAD_GRAYSCALE)
#提取輸入影象的高度
h, w = img.shape

"""
索貝爾濾波器:是一種邊檢測器,它使用3x3核心來檢測水平邊和垂直邊
"""
sobel_horizontal = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=5)
"""執行索貝爾垂直檢測器"""
sobel_vertical = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=5)
"""
拉普拉斯邊檢測器:可以檢測兩個方向上的邊
"""
laplacian = cv2.Laplacian(img, cv2.CV_64F)
"""
儘管拉普拉斯邊檢測器彌補了索貝爾邊檢測器的不足,但是拉普拉斯邊檢測器的輸出仍然帶有很多噪聲
Canny邊檢測器:在解決噪聲問題方面優於拉普拉斯邊檢測器和索貝爾邊檢測器。
Canny邊檢測器是一個分階段的處理過程,它用到了遲滯性來做邊資料清理。
"""
canny = cv2.Canny(img, 50, 240)
#顯示所有影象
cv2.imshow('Original', img)
cv2.imshow('Sobel horizontal', sobel_horizontal)
cv2.imshow('Sobel vertical', sobel_vertical)
cv2.imshow('Laplacian', laplacian)
cv2.imshow('Canny', canny)

cv2.waitKey()

在cmd執行:python 檔名.py chair.jpg

原始圖片:
這裡寫圖片描述
索貝爾水平邊檢測器的輸出:它檢測到的邊大致都是垂直的,這是因為它是一個水平邊檢測器,它能檢測出在水平方向上的變化。
這裡寫圖片描述
索貝爾垂直邊的輸出:
這裡寫圖片描述
拉普拉斯邊檢測器的輸出:
這裡寫圖片描述
Canny邊檢測器較好地檢測了所有的邊:
這裡寫圖片描述

直方圖均衡化
直方圖均衡化:是指修改影象的畫素,以增強影象的對比強度的過程。
用到的圖片 sunrise.jpg
這裡寫圖片描述

程式碼:

import sys
import cv2
import numpy as np

# 載入輸入圖片 -- 'sunrise.jpg'
input_file = sys.argv[1]
img = cv2.imread(input_file)

# 轉化為灰度圖並顯示出來
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('Input grayscale image', img_gray)

# 均衡直方圖,並顯示出來
img_gray_histeq = cv2.equalizeHist(img_gray)
cv2.imshow('Histogram equalized - grayscale', img_gray_histeq)


# 均衡彩色影象直方圖
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
#均衡Y通道
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
#將其轉化為BGR
img_histeq = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
#顯示輸入和輸出影象
cv2.imshow('Input color image', img)
cv2.imshow('Histogram equalized - color', img_histeq)

cv2.waitKey()

在cmd執行:python 檔名.py sunrise.jpg
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

3.檢測稜角
檢測稜角是計算機視覺中的一個重要環節,它幫助我們識別影象中突出的點,這是用於開發影象分析系統中最早期的特徵提取技術之一。

用到的圖片 box.png
這裡寫圖片描述

程式碼:

import sys
import cv2
import numpy as np

# 載入輸入物件 -- 'box.png'
input_file = sys.argv[1]
img = cv2.imread(input_file)
cv2.imshow('Input image', img)

#將影象轉為灰度,並將其強制轉化為浮點值,浮點值用於稜角檢測過程
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img_gray = np.float32(img_gray)

# 哈里斯角檢測器
img_harris = cv2.cornerHarris(img_gray, 7, 5, 0.04)

# 放大影象,以標記稜角
img_harris = cv2.dilate(img_harris, None)

# 用閾值顯示稜角
img[img_harris > 0.01 * img_harris.max()] = [0, 0, 0]
#顯示輸出影象
cv2.imshow('Harris Corners', img)
cv2.waitKey()

在cmd執行:python 檔名.py box.png
原始輸入影象:
這裡寫圖片描述
檢測稜角處理後圖像:
這裡寫圖片描述

4.檢測SIFT特徵點
尺度不變特徵變換(SIFT)是計算機視覺領域最常用的特徵之一。SIFT成為影象識別和影象內容分析領域最有效的特徵之一,它在大小,方向,對比度等方向都有較強的健壯性。SIFT也是目標識別系統的基礎。

用到的圖片:table.jpg
這裡寫圖片描述

程式碼:

import sys
import cv2
import numpy as np


# 載入影象 -- 'table.jpg'
input_file = sys.argv[1]
img = cv2.imread(input_file)

#將影象轉為灰度
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#初始化SIFT檢測物件並提取關鍵點:
sift = cv2.xfeatures2d.SIFT_create()
keypoints = sift.detect(img_gray, None)


#在輸入影象上畫出關鍵點
img_sift = np.copy(img)
cv2.drawKeypoints(img, keypoints, img_sift, flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
#顯示輸入和輸出影象
cv2.imshow('Input image', img)
cv2.imshow('SIFT features', img_sift)
cv2.waitKey()

cmd執行:python 檔名.py chair.jpg

這裡寫圖片描述
這裡寫圖片描述

注意:所有執行的檔案要和用到的圖片在同一路徑下。

5.建立Star特徵檢測器

SIFI特徵檢測器在很多場景中都很好用,但是,當建立目標識別系統時,在用SIFI檢測特徵之前,可能需要用到一個不同的特徵檢測器,Star特徵檢測器,這使我們能夠通過靈活地層疊不同的模組來獲得最佳效能。

import sys
import cv2
import numpy as np

class StarFeatureDetector(object):
    def __init__(self):
        self.detector = cv2.xfeatures2d.StarDetector_create()

    def detect(self, img):
        return self.detector.detect(img)

if __name__=='__main__':
    # 載入圖片 -- 'table.jpg'
    input_file = sys.argv[1]
    input_img = cv2.imread(input_file)

    # 轉化為灰度圖
    img_gray = cv2.cvtColor(input_img, cv2.COLOR_BGR2GRAY)

    # 用Star特徵檢測器檢測出特徵
    keypoints = StarFeatureDetector().detect(input_img)

    # 畫出輸入影象的關鍵點
    cv2.drawKeypoints(input_img, keypoints, input_img, 
            flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    #顯示輸出影象
    cv2.imshow('Star features', input_img)

    cv2.waitKey()

執行結果:
這裡寫圖片描述

識別圖中所有人臉

face_recognition ,開源的人臉識別庫,離線識別率高達99.38%。
安裝:pip install face_recognition
安裝的過程,可能在dlib這個環節報錯。dlib需要手動安裝。可在百度中尋找安裝方法。

用到的圖片:1.jpg
這裡寫圖片描述

程式碼:


# -*- coding: utf-8 -*-
from PIL import Image
import face_recognition

# 將jpg檔案載入到numpy 陣列中
image = face_recognition.load_image_file("1.jpg")
face_locations = face_recognition.face_locations(image)

# 使用CNN模型
# face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn")

# 列印:我從圖片中找到了 多少 張人臉
print("I found {} face(s) in this photograph.".format(len(face_locations)))

# 迴圈找到的所有人臉
for face_location in face_locations:

        # 列印每張臉的位置資訊
        top, right, bottom, left = face_location
        print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))

        # 指定人臉的位置資訊,然後顯示人臉圖片
        face_image = image[top:bottom, left:right]
        pil_image = Image.fromarray(face_image)
        pil_image.show()

執行結果,輸出所有人臉。

自動識別人臉特徵

用到的圖片 2.jpg
這裡寫圖片描述

程式碼:

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw
import face_recognition
image = face_recognition.load_image_file("2.jpg")


face_landmarks_list = face_recognition.face_landmarks(image)

print("I found {} face(s) in this photograph.".format(len(face_landmarks_list)))

for face_landmarks in face_landmarks_list:
    facial_features = [
        'chin',
        'left_eyebrow',
        'right_eyebrow',
        'nose_bridge',
        'nose_tip',
        'left_eye',
        'right_eye',
        'top_lip',
        'bottom_lip'
    ]

    for facial_feature in facial_features:
        print("The {} in this face has the following points: {}".format(facial_feature, face_landmarks[facial_feature]))

    pil_image = Image.fromarray(image)
    d = ImageDraw.Draw(pil_image)

    for facial_feature in facial_features:
        d.line(face_landmarks[facial_feature], width=5)

    pil_image.show()

識別人臉並美顏

程式碼:

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw
import face_recognition

#將jpg檔案載入到numpy陣列中
image = face_recognition.load_image_file("3.jpg")

#查詢影象中所有面部的所有面部特徵
face_landmarks_list = face_recognition.face_landmarks(image)

for face_landmarks in face_landmarks_list:
    pil_image = Image.fromarray(image)
    d = ImageDraw.Draw(pil_image, 'RGBA')

    #讓眉毛變成了一場噩夢
    d.polygon(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 128))
    d.polygon(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 128))
    d.line(face_landmarks['left_eyebrow'], fill=(68, 54, 39, 150), width=5)
    d.line(face_landmarks['right_eyebrow'], fill=(68, 54, 39, 150), width=5)


    #光澤的嘴脣
    d.polygon(face_landmarks['top_lip'], fill=(150, 0, 0, 128))
    d.polygon(face_landmarks['bottom_lip'], fill=(150, 0, 0, 128))
    d.line(face_landmarks['top_lip'], fill=(150, 0, 0, 64), width=8)
    d.line(face_landmarks['bottom_lip'], fill=(150, 0, 0, 64), width=8)

    #閃耀眼睛
    d.polygon(face_landmarks['left_eye'], fill=(255, 255, 255, 30))
    d.polygon(face_landmarks['right_eye'], fill=(255, 255, 255, 30))

    #塗一些眼線
    d.line(face_landmarks['left_eye'] + [face_landmarks['left_eye'][0]], fill=(0, 0, 0, 110), width=6)
    d.line(face_landmarks['right_eye'] + [face_landmarks['right_eye'][0]], fill=(0, 0, 0, 110), width=6)

    pil_image.show()