python3__深度學習:計算機視覺__OpenCV的安裝及使用(旋轉後圖像黑邊的去除未完成)
1.OpenCV庫的安裝與使用
OpenCV全稱為Open Source Computer Vision Library,是Intel公司支援開發的計算機視覺處理開源軟體庫,採用C或C++編寫,同樣提供了Python、MATLAB等語言的介面,可以自由的與醒來linux、Windows、Mac等多平臺作業系統中。其充分利用了Intel處理器的高效能多媒體函式庫的手工優化效能,提高了執行速度。其覆蓋了醫學影像、設計外觀、定位標記、生物體檢測等多個行業領域。
1.1 庫下載連結
https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv
1.2 庫安裝
Anaconda Prompt: pip install *.whl
引用形式:import cv2
2.OpenCV的基本圖片讀取
2.1 圖片儲存形式
在計算機中圖片是以矩陣的形式儲存在儲存介質中的。在OpenCV中三原色(RGB)的排列順序為BGR。
import pandas as pd import numpy as np import matplotlib.pyplot as plt import cv2 img = np.mat(np.zeros((300, 300), dtype=np.uint8)) print(img.shape) # cvtColor:Converts an image from one color space to another # COLOR_GRAY2BGR: 色彩空間轉化的全域性變數 img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR) print(img.shape) # Displays an image in the specified window cv2.imshow("test", img) # Waits for a pressed key cv2.waitKey(0)
2.2 影象的讀取與儲存
imread(filename, flags=None): Loads an image from a file.If the image cannot be read (because of missing file, improper permissions, unsupported or invalid format), the function . returns an empty matrix ( Mat::data==NULL )。該函式在讀取圖片的時候會刪除所有圖片Alpha通道資訊。
引數:
filename: 待讀取的檔名
flags: 讀取之後被自動處理我何種色彩空間。設定為cv2中的全域性變數。
imwrite(filename, img, params=None): Saves an image to a specified file. In general, only 8-bit . single-channel or 3-channel (with 'BGR' channel order) images . can be saved using this function. 要求輸出的圖片格式為BGR或者灰度圖。
引數:
filename: 待儲存圖片的名稱
img: 圖片所對應的矩陣
import numpy as np
import cv2
img = cv2.imread("maxin.jpg")
print(img.shape) # (2000, 1360, 3)
img = cv2.imread("maxin.jpg", cv2.IMREAD_GRAYSCALE)
print(img.shape) # (2000, 1360)
cv2.imwrite("maxin.png", img)
2.3 影象的轉換
在計算機中儲存的時候,任何一個圖片的儲存都佔有一定的空間,而為了減少圖片的儲存便於在有限的記憶體中更進一步的轉換,對於每個圖片來說,可以通過python自帶的bytearray()函式對其進行轉換。同樣,bytearray可通過矩陣重構的方式轉換為原本的圖片矩陣。
import numpy as np
import cv2
import os
imgByteArray = bytearray(os.urandom(90000))
imgBGR = np.array(imgByteArray).reshape(300, 300)
cv2.imshow("cool", imgBGR)
cv2.waitKey(0)
2.4 Numpy對影象的編輯
由於影象在記憶體中的儲存是通過矩陣的形式儲存的,因此,可直接通過numpy對某一位置進行修改。下部程式碼中,在讀取的圖片中畫了兩條白色的線。
import numpy as np
import cv2
img = cv2.imread("maxin.jpg", cv2.IMREAD_GRAYSCALE)
print(img)
print(img.shape) # (2000, 1360)
img[:, 700] = 255
img[680, :] = 255
cv2.imshow(winname="img", mat=img)
cv2.waitKey(0)
3.OpenCV卷積處理
3.1 計算機視覺中常用的3中色彩空間
(1)灰度:僅保留黑白資訊的色彩空間稱為灰度空間。一般而言,灰度空間對人臉的處理特別有效。
(2)BGR: 在該空間中,每一個畫素都是由一個三維陣列表示的,分別代表藍、綠、紅三種顏色,且是OpenCV中的主要色彩空間。
(3)HSV: H是色調; S是飽和度; V是黑色度
3.2 卷積核與影象特徵提取
卷積核:
在OpenCV甚至是平常的影象處理中,卷積核是一種最常用的影象處理工具。其主要是通過確定的核塊來檢測影象的某個區域,後根據所檢測的畫素與其周圍存在的畫素的亮度差值來改變畫素明亮度的工具。
3.3 特徵提取方式一:多維卷積
convolve(input, weights, output=None, mode='reflect', cval=0.0, origin=0):多維卷積
引數:
input: 輸入的圖片陣列(array_like)
weights: 卷積核
mode: 亮度調節的方式(constant, reflect, nearest)
cval: 輸入陣列外邊緣的填充值
import numpy as np
import cv2
# ndimage: Multi-dimensional image processing
from scipy import ndimage
kernel33 = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
kernel33_D = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
# 讀取時直接轉換為灰度圖
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
lightImg = ndimage.convolve(img, kernel33_D, mode="reflect", cval=0)
print(lightImg)
cv2.imshow("img", img)
cv2.waitKey(0)
3.4 特徵提取方式二:高斯模糊
GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None): Blurs an image using a Gaussian filter
引數:
src: 圖片陣列,可為任何通道數
ksize: 高斯核的大小。(width, height) -> 長寬可以不同,但兩者必須為正的奇數
sigmaX: x方向的高斯核標準差
sigmaY: y方向的高斯核標準差。如果sigmaY為零,則將其設定為等於sigmaX,如果兩個sigma均為零,則分別從ksize.width和ksize.height計算(有關詳細資訊,請參閱#getGaussianKernel); 為了完全控制結果,無論將來可能修改所有這些語義,建議指定所有ksize,sigmaX和sigmaY。
dst: output image of the same size and type as src
borderType: 畫素外推法
import numpy as np
import cv2
from scipy import ndimage
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
blurred = cv2.GaussianBlur(img, (11, 11), sigmaX=0)
gaussImg = img - blurred
cv2.imshow("GaussianBlur", gaussImg)
cv2.waitKey()
3.5 卷積的具體實現
import numpy as np
import cv2
from scipy import ndimage
def myConvolve(dataMat, kernel):
"""
design my convolve function
:param dataMat: img Mat (256, 256)
:param kernel: convolve (3, 3)
:return: Convolution kernel
"""
m, n = dataMat.shape
km, kn = kernel.shape
newMat = np.ones((m-km+1, n-kn+1))
tempMat = np.ones((km, kn))
for row in range(m-km+1):
for col in range(n-kn+1):
for m_k in range(km):
for n_k in range(kn):
tempMat[m_k, n_k] = dataMat[(row+m_k), (col+n_k)] * kernel[m_k, n_k]
newMat[row, col] = np.sum(tempMat)
return newMat
# (256, 256)
img = cv2.imread("lena.jpg", cv2.IMREAD_GRAYSCALE)
kernel33_D = np.array([[1, 1, 1], [1, -8, 1], [1, 1, 1]])
# (254, 254)
lightImg = myConvolve(img, kernel33_D)
# # 該函式實際上計算的是相關性,而並非卷積
# lightImg = cv2.filter2D(img, -1, kernel33_D)
# lightImg = ndimage.convolve(img, kernel33_D)
cv2.imshow("my_convolve", lightImg)
cv2.waitKey()
4.OpenCV影象的擴縮裁挖
【擴縮】:
cv.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None): 對影象進行擴縮
引數:
src: 待調整大小的圖片矩陣
dsize: 調整後圖片的大小(矩陣的x和y)。若dsize=0, 則為(round(fx*src.cols), round(fy*src.rows))。因此,dsize和fx\fy不能同時為0.
dst: 與src同類型的調整後的輸出矩陣
fx/fy: 比例因子,即調整後的圖片大小的x和y分別為src中x和y的多少倍。when fx/fy==0, fx = (dsize.width/src.cols), fy = (dsize.height/src.rows)
【挖掘】
即單純的陣列、矩陣操作
import tensorflow as tf
from scipy import ndimage
import cv2
import numpy as np
img = cv2.imread("leaf.png", cv2.IMREAD_GRAYSCALE)
# 放縮
imgBig = cv2.resize(img, (600, 600))
imgSml = cv2.resize(img, (100, 100))
cv2.imshow("Big", imgBig)
cv2.imshow("real", img)
cv2.imshow("Small", imgSml)
# 裁挖
part_of_imgBig = imgBig[200:, 25:575]
cv2.imshow("part", part_of_imgBig)
cv2.waitKey()
5.影象色調調整
cv2除了能夠對影象的區域進行設定、自由拉伸和裁剪已有的影象,同樣可以對圖片的色調(H:[0, 180])、飽和度(S: [0, 255])、明暗度(V: [0, 255])
5.1 色調調整
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# cvtColor: Converts an image from one color space to another
# 將BGR轉換成HSV色彩空間
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
turn_green_hsv = img_hsv.copy()
# 每個畫素點減30個色調,即黃色被大範圍縮減(黃色被大範圍縮減)
turn_green_hsv[:, :, 0] = (turn_green_hsv[:, :, 0] - 1000) % 180
turn_green_img = cv2.cvtColor(turn_green_hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("change_H", turn_green_img)
cv2.waitKey()
5.2 飽和度調整
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# cvtColor: Converts an image from one color space to another
# 將BGR轉換成HSV色彩空間
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
less_color_hsv = img_hsv.copy()
# 降低圖片的飽和度,使得色調變灰
less_color_hsv[:, :, 1] = less_color_hsv[:, :, 1] * 0.1
less_color_img = cv2.cvtColor(less_color_hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("change_H", less_color_img)
cv2.waitKey()
5.3 明暗度調整
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# cvtColor: Converts an image from one color space to another
# 將BGR轉換成HSV色彩空間
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
less_light_hsv = img_hsv.copy()
# 降低圖片的亮度
less_light_hsv[:, :, 2] = less_light_hsv[:, :, 2] * 0.5
less_light_img = cv2.cvtColor(less_light_hsv, cv2.COLOR_HSV2BGR)
cv2.imshow("change_H", less_light_img)
cv2.waitKey()
5.4 增強圖片細節
Gamma變換主要是為了減少計算機視覺與人眼視覺的差異()而做的計算方式,但是在深度學習中,可作為噪聲修改的方式增大資料量。
gamma > 1, 影象變暗; gamma < 1, 影象變亮
import cv2
import numpy as np
import pandas as pd
from scipy import ndimage
import matplotlib.pyplot as plt
# plt.imread: Return value is a :class:`numpy.array`. For grayscale images, the return array is MxN.
# For RGB images, the return value is MxNx3. For RGBA images the return value is MxNx4.
img = cv2.imread("leaf.png")
gamma = 2
# 先歸一化,gamma作為指數,求出新畫素值再還原
# np.round: 將陣列舍入到給定的小數
gamma_change = [np.power(x/255, gamma) * 255 for x in range(256)]
gamma_img = np.round(np.array(gamma_change), 2).astype(np.uint8)
# cv2.LUT: 實現對映用的是Opencv的查表函式
img_corrected = cv2.LUT(src=img, lut=gamma_img)
plt.subplot(121)
plt.imshow(img)
plt.subplot(122)
plt.imshow(img_corrected)
plt.show()
6.影象的旋轉,平移和翻轉
該方法是深度學習對圖片處理的常用功能,可以極大的增加資料量。
cv2.wrapAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
引數:
src: 待處理的圖片原始矩陣
M: 仿射矩陣
dsize: 輸出圖片矩陣的大小
borderMode: 畫素外推法,實際上設定的是變換後的圖片怎樣顯示
import cv2
import numpy as np
img = cv2.imread("leaf.png")
# 仿射矩陣
# 第三列:原點座標
# 第二列:y軸座標
# 第一列:x軸座標
M_copy_img = np.array([[0, 0.8, -100],
[0.8, 0, -12]], dtype=np.float32)
# cv2.warpAffine:對影象應用仿射變換
# borderMode=cv2.BORDER_TRANSPARENT: 這意味著該功能不會修改與源影象中的“異常值”對應的目標影象中的畫素(即:修改後的圖
# 像直接列印在原始影象之上)
img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_TRANSPARENT)
# img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_CONSTANT)
# img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_DEFAULT)
# img_change = cv2.warpAffine(img, M_copy_img, (300, 300), borderMode=cv2.BORDER_REFLECT)
cv2.imshow("test", img_change)
cv2.waitKey()
7.OpenCV擴大影象資料庫
見本部落格文章