雖然計算機視覺領域目前基本是以深度學習算法爲主,但實際上不少時候對圖片的不少處理方法,並不須要採用深度學習的網絡模型,採用目前成熟的圖像處理庫便可實現,好比 OpenCV 和 PIL ,對圖片進行簡單的調整大小、裁剪、旋轉,或者是對圖片的模糊操做。html
因此本文主要是介紹用 OpenCV 實現一些基本的圖像處理操做,本文的目錄以下所示:python
原文地址:git
https://likegeeks.com/python-image-processing/github
代碼和樣例圖片的地址:算法
https://github.com/ccc013/CodesNotes/tree/master/opencv_noteswindows
https://github.com/ccc013/CodesNotes/blob/master/opencv_notes/opencv_image_process_tutorial.ipynb數組
OpenCV 的安裝仍是比較簡單的,直接用 pip
命令在命令行安裝便可,輸入如下命令:網絡
pip install opencv-python
驗證是否安裝成功,能夠運行 python
命令,而後分別輸入如下命令:函數
import cv2
運行成功,沒有報錯,即安裝成功。學習
首先,仍是須要導入 cv2
模塊:
import cv2
而後第一件事情就是讀取圖片,調用imread
函數便可,輸入參數是圖片的路徑,以下代碼所示:
# 讀取圖片 img = cv2.imread('example.jpg') print(f'type: {type(img)}') plt.axis('off') plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
而後打印讀取的圖片類型,能夠知道是一個numpy
的多維數組,即矩陣的形式。
上述代碼運行結果以下:
下面的全部功能實現,我都是在 jupyter notebook
上實現的,因此展現圖片部分和原文有所不一樣,原文展現圖片代碼是採用:
cv2.imshow('original image', img) cv2.waitKey(0)
而在 jupyter 中,須要先導入下面的庫:
import matplotlib.pyplot as plt %matplotlib inline
而後直接調用 plt.imshow()
函數,不過 opencv 都須要作一個轉換過程,即:
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
讀取好圖片後,接下來就是實現旋轉圖片,這裏分爲如下三個步驟:
cv2.getRotationMatrix2D()
獲得旋轉矩陣wrapAffine
實現旋轉實現的代碼以下所示:
# 獲取圖片的寬、高 height, width = img.shape[:2] print(height, width) rotationMatrix = cv2.getRotationMatrix2D((width/2, height/2), 45, .5) rotationImage = cv2.warpAffine(img, rotationMatrix, (width, height)) print(f'rotation image shape:{rotationImage.shape}') plt.imshow(cv2.cvtColor(rotationImage, cv2.COLOR_BGR2RGB))
結果以下所示:
裁剪圖片的步驟以下:
實現代碼以下所示:
img = cv2.imread('example.jpg') height, width = img.shape[:2] print(f'origin image shape:{img.shape}') # 設置裁剪後圖片的大小 start_row = int(height * 0.15) start_col = int(width * 0.15) end_row = int(height * 0.85) end_col = int(width * 0.85) # 裁剪圖片 cropped_image = img[start_row:end_row, start_col:end_col] print(f'crop image shape:{cropped_image.shape}') plt.axis('off') plt.imshow(cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB))
效果以下圖所示:
對圖片進行調整大小的操做,採用的是resize()
函數,這裏有兩種方式進行調整大小:
fx, fy
參數;第一種方式的實現代碼:
img = cv2.imread('example.jpg') height, width = img.shape[:2] print(f'origin image shape:{img.shape}') # 1 new_img = cv2.resize(img, (0, 0), fx=0.75, fy=0.75) print(f'new img shape:{new_img.shape}') plt.axis('off') plt.imshow(cv2.cvtColor(new_img, cv2.COLOR_BGR2RGB))
實現效果:
第二種方法的實現代碼:
# 2 new_img = cv2.resize(img, (800, 800)) print(f'new img shape:{new_img.shape}') plt.axis('off') plt.imshow(cv2.cvtColor(new_img, cv2.COLOR_BGR2RGB))
實現結果以下所示:
在 Python 的 OpenCV 模塊中並無特定的實現調整圖片對比度的函數,但官方文檔給出實現調整圖片亮度和對比度的公式,以下所示:
new_img = a*original_img + b
官方文檔地址:
https://docs.opencv.org/master/d3/dc1/tutorial_basic_linear_transform.html
這裏公式中的 a
就是 $\alpha$, 表示圖片的對比度,
b
是 $\beta$ ,數值範圍是 -127 到 127;
要實現上述公式,能夠採用 addWeighted()
方法,它輸出的圖片是一個 24 位的 0-255 範圍的彩色圖片。
其語法以下所示:
cv2.addWeighted(source_img1, alpha1, source_img2, alpha2, beta)
這個方法是接收兩張輸入的圖片,而後根據 alpha1
和 alpha2
來將兩種圖片進行融合。
若是隻是想調整圖片的對比度,那麼能夠將第二個圖片經過 Numpy 設置爲 0。
因此,實現的代碼以下所示:
import numpy as np img = cv2.imread('example.jpg') # 高對比度 hight_contrast_img = cv2.addWeighted(img, 2.5, np.zeros(img.shape, img.dtype), 0, 0) # 低對比度 low_contrast_img = cv2.addWeighted(img, 0.5, np.zeros(img.shape, img.dtype), 0, 0) plt.figure(figsize=(32, 16)) plt.subplot(3, 1, 1) plt.title('origin image') plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(3, 1, 2) plt.title('hight contrast image') plt.imshow(cv2.cvtColor(hight_contrast_img, cv2.COLOR_BGR2RGB)) plt.subplot(3, 1, 3) plt.title('low contrast image') plt.imshow(cv2.cvtColor(low_contrast_img, cv2.COLOR_BGR2RGB))
實現效果以下所示:
高斯模糊採用的是 GaussianBlur()
方法,採用高斯核,而且核的寬和高必須是正數,且是奇數。
高斯濾波主要用於消除高斯噪聲,能夠保留更多的圖像細節,常常被稱爲最有用的濾波器。
實現的代碼以下所示:
img = cv2.imread('example.jpg') blur_img = cv2.GaussianBlur(img, (7, 7), 3) plt.figure(figsize=(32, 32)) plt.subplot(1, 2, 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(1, 2, 2) plt.imshow(cv2.cvtColor(blur_img, cv2.COLOR_BGR2RGB))
實現效果:
對於中值模糊,就是用區域內的中值來代替本像素值,所以孤立的斑點,好比 0 或者 255 的數值很容易消除掉。
因此中值模糊主要用於消除椒鹽噪聲和斑點噪聲。
實現代碼:
img = cv2.imread('example.jpg') blur_img = cv2.medianBlur(img, 5) plt.figure(figsize=(32, 32)) plt.subplot(1, 2, 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(1, 2, 2) plt.imshow(cv2.cvtColor(blur_img, cv2.COLOR_BGR2RGB))
實現效果以下所示:
邊緣檢測主要是經過Canny()
方法,它實現了 Canny 邊緣檢測器,這也是目前最優的邊緣檢測器。
Canny()
方法的語法以下:
cv2.Canny(image, minVal, maxVal)
其中 minVal
和 maxVal
分別表示梯度強度值的最小值和最大值。
實現代碼以下:
img = cv2.imread('example.jpg') edge_img = cv2.Canny(img, 100, 200) plt.figure(figsize=(32, 32)) plt.subplot(1, 2, 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(1, 2, 2) plt.imshow(cv2.cvtColor(edge_img, cv2.COLOR_BGR2RGB))
實現結果:
最簡單的將圖片轉爲灰度圖的方法,就是讀取的時候,代碼以下所示:
img = cv2.imread("example.jpg", 0)
而另外一種方法就是用 BGR2GRAY
,實現代碼:
img = cv2.imread('example.jpg') gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) plt.figure(figsize=(32, 32)) plt.subplot(1, 2, 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(1, 2, 2) plt.imshow(cv2.cvtColor(gray_img, cv2.COLOR_BGR2RGB))
實現效果:
檢測一張圖片的形心位置,實現步驟以下所示:
moments()
方法計算圖片的 moments
;本例使用的圖片以下:
實現代碼:
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) moment = cv2.moments(gray_img) X = int(moment ["m10"] / moment["m00"]) Y = int(moment ["m01"] / moment["m00"]) cv2.circle(img, (X, Y), 50, (205, 114, 101), 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
實現的效果:
圖像蒙版就是將一張圖片做爲另外一張圖片的蒙版,或者是修改圖片中的像素值。
本例中將採用HoughCircles()
方法來應用蒙版,這個方法能夠檢測圖片中的圓,而後對這些圓應用蒙版。
本例採用的圖片爲:
實現代碼:
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) circles = cv2.HoughCircles(gray_img, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=50, minRadius=0, maxRadius=0) circles = np.uint16(np.around(circles)) masking=np.full((img1.shape[0], img1.shape[1]),0,dtype=np.uint8) for j in circles[0, :]: cv2.circle(masking, (j[0], j[1]), j[2], (255, 255, 255), -1) final_img = cv2.bitwise_or(img1, img1, mask=masking) plt.imshow(cv2.cvtColor(final_img, cv2.COLOR_BGR2RGB))
實現效果:
實現提取圖片的文字是經過安裝使用谷歌的 Tesseract-OCR
,首先須要從下面這個網址中下載:
https://digi.bib.uni-mannheim.de/tesseract/tesseract-ocr-setup-3.05.02-20180621.exe
接着再進行安裝:
pip install pytesseract
若是是 mac,安裝步驟能夠是這樣的:
brew install tesseract pip install pytesseract
本例使用的圖片:
實現代碼以下所示:
import pytesseract pytesseract.pytesseract.tesseract_cmd = '/usr/local/bin/tesseract' img = cv2.imread('pytext.png') pytesseract.image_to_string(img)
實現結果:
注意這裏須要設置 tesseract
的執行路徑,兩種方法,第一種是設置環境變量:
windows 版:https://blog.csdn.net/luanyongli/article/details/81385284
第二種是在代碼中進行指定,即代碼中pytesseract.pytesseract.tesseract_cmd = '/usr/local/bin/tesseract'
,
這裏我用的是 Mac,因此這個路徑能夠在命令行中輸入which tesseract
來找到。
在本例中,使用的圖片以下:
首先仍是先讀取圖片,並轉換爲灰度圖:
接着採用 bitwise_not
方法將背景和文字顏色進行交換,變成白字黑底:
接着分別找到 x,y 座標中大於 0 值的像素值,並經過minAreaRect()
計算獲得歪曲的角度,接着就是計算要修正的角度,而後再經過以前旋轉圖片的方法來修正,實現代碼和結果以下:
完整的實現代碼:
import cv2 import numpy as np img = cv2.imread('Skewed-text-image.png') gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray_img = cv2.bitwise_not(gray_img) coordinates = np.column_stack(np.where(gray_img > 0)) ang=cv2.minAreaRect(coordinates)[-1] if ang<-45: angle=-(90+ang) else: angle=-ang height, width = img.shape[:2] center_img = (width / 2, height / 2) rotationMatrix = cv2.getRotationMatrix2D(center_img, angle, 1.0) rotated_img = cv2.warpAffine(img, rotationMatrix, (width, height), borderMode = cv2.BORDER_REFLECT) plt.imshow(cv2.cvtColor(rotated_img, cv2.COLOR_BGR2RGB))
在本次例子中實現檢測圖片中的綠色區域,使用的圖片:
首先是讀取圖片後,轉換到 HSV 空間:
接着須要經過 Numpy 設置綠色像素值的上下範圍區間:
lower_green = np.array([34, 177, 76]) upper_green = np.array([255, 255, 255])
接着經過 inRange()
方法來判斷輸入圖片中是否包含在設置後的綠色區間範圍內,若是有,那就表示檢測到綠色這種顏色的像素區域。
完整實現的代碼:
import cv2 import numpy as np img = cv2.imread("pycolor.png") hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) plt.imshow(cv2.cvtColor(hsv_img, cv2.COLOR_BGR2RGB)) lower_green = np.array([34, 177, 76]) upper_green = np.array([255, 255, 255]) masking = cv2.inRange(hsv_img, lower_green, upper_green) plt.imshow(cv2.cvtColor(masking, cv2.COLOR_BGR2RGB))
實現結果:
OpenCV 中提供了下面 4 種圖像去噪的方法:
fastNlMeansDenoising()
:從灰度圖中降噪;fastNlMeansDenoisingColored()
:從彩色圖片中降噪fastNlMeansDenoisingMulti()
:從灰度圖片幀(灰度視頻)中降噪;fastNlMeansDenoisingColoredMulti()
:從彩色圖片幀中降噪本次例子會用第二種方法:fastNlMeansDenoisingColored()
實現的代碼以下所示:
import cv2 img = cv2.imread('example.jpg') result = cv2.fastNlMeansDenoisingColored(img,None,20,10,7,21) plt.figure(figsize=(32, 32)) plt.subplot(1, 2, 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(1, 2, 2) plt.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
其中對於方法fastNlMeansDenoisingColored()
的個參數分別是:
result
變量裏;實現結果:
輪廓是圖片中將連續的點鏈接在一塊兒的曲線,一般檢測輪廓的目的是爲了檢測物體。本例中使用的圖片以下:
檢測輪廓的步驟以下:
threshold
() 找到閾值,一般設置 127-255 的區間findContours()
進行檢測輪廓,具體使用方法能夠查看官方文檔:https://docs.opencv.org/3.4.2/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689adrawContours()
來繪製畫好的輪廓,而後展現出來實現代碼:
import cv2 img = cv2.imread('opencv_contour_example.png') gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) retval, thresh = cv2.threshold(gray_img, 127, 255, 0) img_contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img, img_contours, -1, (0, 255, 0)) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
實現效果:
移除圖片背景的實現思路是這樣的:
np.zeros
生成一個蒙版 mask;bitwise_and
運算符來結合檢測輪廓後的圖片和蒙版 mask本次樣例使用的原圖:
實現代碼:
import cv2 import numpy as np img = cv2.imread("opencv_bg.png") gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, thresh = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) img_contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2] img_contours = sorted(img_contours, key=cv2.contourArea) for i in img_contours: if cv2.contourArea(i) > 100: break mask = np.zeros(img.shape[:2], np.uint8) cv2.drawContours(mask, img_contours, -1, 255, -1) new_img = cv2.bitwise_and(img, img, mask=mask) plt.figure(figsize=(32, 32)) plt.subplot(1, 2, 1) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.subplot(1, 2, 2) plt.imshow(cv2.cvtColor(new_img, cv2.COLOR_BGR2RGB))
實現結果:
本文是簡單介紹了基於 opencv 實現的一些圖像處理操做,從基礎的旋轉,裁剪,調整大小,到模糊圖片,邊緣檢測,修正歪曲文字,去噪,檢測輪廓等操做,都給出了基礎的實現代碼,若是須要更深刻了解,這裏推薦:
最後,原文地址:
https://likegeeks.com/python-image-processing/
代碼和樣例圖片的地址:
https://github.com/ccc013/CodesNotes/tree/master/opencv_notes
https://github.com/ccc013/CodesNotes/blob/master/opencv_notes/opencv_image_process_tutorial.ipynb
歡迎關注個人公衆號--算法猿的成長