基于 opencv 的图像处理入门教程
點擊上方“算法猿的成長“,關(guān)注公眾號,選擇加“星標“或“置頂”
總第 146?篇文章,本文大約?5000?字,閱讀大約需要?20?分鐘
前言
雖然計算機視覺領(lǐng)域目前基本是以深度學習算法為主,但實際上很多時候?qū)D片的很多處理方法,并不需要采用深度學習的網(wǎng)絡(luò)模型,采用目前成熟的圖像處理庫即可實現(xiàn),比如 OpenCV 和 PIL ,對圖片進行簡單的調(diào)整大小、裁剪、旋轉(zhuǎn),或者是對圖片的模糊操作。
所以本文主要是介紹用 OpenCV 實現(xiàn)一些基本的圖像處理操作,本文的目錄如下所示:
安裝
旋轉(zhuǎn)圖片
裁剪圖片
調(diào)整圖片大小
調(diào)整圖片對比度
模糊圖片
高斯模糊
中值模糊
邊緣檢測
轉(zhuǎn)為灰度圖
形心檢測
對彩色圖片采用蒙版(mask)
提取圖片的文字(OCR)
檢測和修正歪曲的文字
顏色檢測
去噪
檢測圖片的輪廓
移除圖片的背景
原文地址:
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
1. 安裝
OpenCV 的安裝還是比較簡單的,直接用 pip 命令在命令行安裝即可,輸入以下命令:
pip?install?opencv-python驗證是否安裝成功,可以運行 python 命令,然后分別輸入以下命令:
import?cv2運行成功,沒有報錯,即安裝成功。
2. 旋轉(zhuǎn)圖片
首先,還是需要導入 cv2 模塊:
import?cv2然后第一件事情就是讀取圖片,調(diào)用imread 函數(shù)即可,輸入?yún)?shù)是圖片的路徑,如下代碼所示:
#?讀取圖片 img?=?cv2.imread('example.jpg') print(f'type:?{type(img)}') plt.axis('off') plt.imshow(cv2.cvtColor(img,?cv2.COLOR_BGR2RGB))然后打印讀取的圖片類型,可以知道是一個numpy 的多維數(shù)組,即矩陣的形式。
上述代碼運行結(jié)果如下:
下面的所有功能實現(xiàn),我都是在 jupyter notebook ?上實現(xiàn)的,所以展示圖片部分和原文有所不同,原文展示圖片代碼是采用:
cv2.imshow('original?image',?img) cv2.waitKey(0)而在 jupyter 中,需要先導入下面的庫:
import?matplotlib.pyplot?as?plt %matplotlib?inline然后直接調(diào)用 plt.imshow() 函數(shù),不過 opencv 都需要做一個轉(zhuǎn)換過程,即:
plt.imshow(cv2.cvtColor(img,?cv2.COLOR_BGR2RGB))讀取好圖片后,接下來就是實現(xiàn)旋轉(zhuǎn)圖片,這里分為以下三個步驟:
獲取圖片的寬和高
調(diào)用函數(shù)cv2.getRotationMatrix2D() 得到旋轉(zhuǎn)矩陣
通過 wrapAffine 實現(xiàn)旋轉(zhuǎn)
讀取圖片,并獲取圖片的寬和高;
確定裁剪后圖片的寬和高;
開始裁剪操作
坐標軸方式來指定縮放比例,即fx, fy 參數(shù);
直接給出調(diào)整后圖片的大小。
如果它大于 1,就是高對比度;
如果在 0-1 之間,那就是低對比度;
等于 1,表示沒有任何變化
讀取圖片,并轉(zhuǎn)為灰度圖;
通過moments() 方法計算圖片的 moments;
接著利用第二步的結(jié)果來計算形心的 x,y 坐標
最后可以繪圖展示檢測的結(jié)果。
fastNlMeansDenoising():從灰度圖中降噪;
fastNlMeansDenoisingColored():從彩色圖片中降噪
fastNlMeansDenoisingMulti():從灰度圖片幀(灰度視頻)中降噪;
fastNlMeansDenoisingColoredMulti():從彩色圖片幀中降噪
輸入的原圖
輸出圖片,不過這里設(shè)置為 None,我們直接保存到 result 變量里;
濾波器強度
和濾波器強度一樣,但針對的是彩色圖片的噪聲,一般設(shè)置為 10;
模板塊像素大小,必須是奇數(shù),一般設(shè)置為 7;
計算給定像素均值的窗口大小
讀取圖片,并轉(zhuǎn)為灰度圖;
通過threshold() 找到閾值,通常設(shè)置 127-255 的區(qū)間
采用 findContours() 進行檢測輪廓,具體使用方法可以查看官方文檔:https://docs.opencv.org/3.4.2/d3/dc0/group__imgproc__shape.html#ga17ed9f5d79ae97bd4c7cf18403e1689a
最后是通過drawContours() 來繪制畫好的輪廓,然后展示出來
檢測圖片主要物體的輪廓;
為背景通過np.zeros 生成一個蒙版 mask;
采用 bitwise_and 運算符來結(jié)合檢測輪廓后的圖片和蒙版 mask
opencv 官方文檔:https://docs.opencv.org/master/d9/df8/tutorial_root.html
https://github.com/ex2tron/OpenCV-Python-Tutorial
圖像處理 100 問:https://github.com/gzr2017/ImageProcessing100Wen
實現(xiàn)的代碼如下所示:
#?獲取圖片的寬、高 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))結(jié)果如下所示:
3. 裁剪圖片
裁剪圖片的步驟如下:
實現(xiàn)代碼如下所示:
img?=?cv2.imread('example.jpg') height,?width?=?img.shape[:2] print(f'origin?image?shape:{img.shape}') #?設(shè)置裁剪后圖片的大小 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))效果如下圖所示:
4. 調(diào)整圖片大小
對圖片進行調(diào)整大小的操作,采用的是resize() 函數(shù),這里有兩種方式進行調(diào)整大小:
第一種方式的實現(xiàn)代碼:
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))實現(xiàn)效果:
第二種方法的實現(xiàn)代碼:
#?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))實現(xiàn)結(jié)果如下所示:
5. 調(diào)整圖片對比度
在 Python 的 OpenCV 模塊中并沒有特定的實現(xiàn)調(diào)整圖片對比度的函數(shù),但官方文檔給出實現(xiàn)調(diào)整圖片亮度和對比度的公式,如下所示:
new_img?=?a*original_img?+?b官方文檔地址:
https://docs.opencv.org/master/d3/dc1/tutorial_basic_linear_transform.html
這里公式中的 a 就是 , 表示圖片的對比度,
b 是 ,數(shù)值范圍是 -127 到 127;
要實現(xiàn)上述公式,可以采用 addWeighted() 方法,它輸出的圖片是一個 24 位的 0-255 范圍的彩色圖片。
其語法如下所示:
cv2.addWeighted(source_img1,?alpha1,?source_img2,?alpha2,?beta)這個方法是接收兩張輸入的圖片,然后根據(jù) alpha1 和 alpha2 來將兩種圖片進行融合。
如果只是想調(diào)整圖片的對比度,那么可以將第二個圖片通過 Numpy 設(shè)置為 0。
所以,實現(xiàn)的代碼如下所示:
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))實現(xiàn)效果如下所示:
6. 模糊圖片
高斯模糊
高斯模糊采用的是 GaussianBlur() 方法,采用高斯核,并且核的寬和高必須是正數(shù),且是奇數(shù)。
高斯濾波主要用于消除高斯噪聲,可以保留更多的圖像細節(jié),經(jīng)常被稱為最有用的濾波器。
實現(xiàn)的代碼如下所示:
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))實現(xiàn)效果:
中值模糊
對于中值模糊,就是用區(qū)域內(nèi)的中值來代替本像素值,因此孤立的斑點,比如 0 或者 255 的數(shù)值很容易消除掉。
所以中值模糊主要用于消除椒鹽噪聲和斑點噪聲。
實現(xiàn)代碼:
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))實現(xiàn)效果如下所示:
7. 邊緣檢測
邊緣檢測主要是通過Canny() 方法,它實現(xiàn)了 Canny 邊緣檢測器,這也是目前最優(yōu)的邊緣檢測器。
Canny() 方法的語法如下:
cv2.Canny(image,?minVal,?maxVal)其中 minVal 和 maxVal 分別表示梯度強度值的最小值和最大值。
實現(xiàn)代碼如下:
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))實現(xiàn)結(jié)果:
8. 轉(zhuǎn)為灰度圖
最簡單的將圖片轉(zhuǎn)為灰度圖的方法,就是讀取的時候,代碼如下所示:
img?=?cv2.imread("example.jpg",?0)而另一種方法就是用 BGR2GRAY ,實現(xiàn)代碼:
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))實現(xiàn)效果:
9. 形心檢測
檢測一張圖片的形心位置,實現(xiàn)步驟如下所示:
本例使用的圖片如下:
實現(xiàn)代碼:
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))實現(xiàn)的效果:
10.對彩色圖片采用蒙版(mask)
圖像蒙版就是將一張圖片作為另一張圖片的蒙版,或者是修改圖片中的像素值。
本例中將采用HoughCircles() 方法來應(yīng)用蒙版,這個方法可以檢測圖片中的圓,然后對這些圓應(yīng)用蒙版。
本例采用的圖片為:
實現(xiàn)代碼:
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))實現(xiàn)效果:
11.提取圖片的文字(OCR)
實現(xiàn)提取圖片的文字是通過安裝使用谷歌的 Tesseract-OCR,首先需要從下面這個網(wǎng)址中下載:
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本例使用的圖片:
實現(xiàn)代碼如下所示:
import?pytesseractpytesseract.pytesseract.tesseract_cmd?=?'/usr/local/bin/tesseract' img?=?cv2.imread('pytext.png') pytesseract.image_to_string(img)實現(xiàn)結(jié)果:
注意這里需要設(shè)置 tesseract 的執(zhí)行路徑,兩種方法,第一種是設(shè)置環(huán)境變量:
windows 版:https://blog.csdn.net/luanyongli/article/details/81385284
第二種是在代碼中進行指定,即代碼中pytesseract.pytesseract.tesseract_cmd = '/usr/local/bin/tesseract',
這里我用的是 Mac,所以這個路徑可以在命令行中輸入which tesseract 來找到。
12. 檢測和修正歪曲的文字
在本例中,使用的圖片如下:
首先還是先讀取圖片,并轉(zhuǎn)換為灰度圖:
接著采用 bitwise_not 方法將背景和文字顏色進行交換,變成白字黑底:
接著分別找到 x,y 坐標中大于 0 值的像素值,并通過minAreaRect() 計算得到歪曲的角度,接著就是計算要修正的角度,然后再通過之前旋轉(zhuǎn)圖片的方法來修正,實現(xiàn)代碼和結(jié)果如下:
完整的實現(xiàn)代碼:
import?cv2 import?numpy?as?npimg?=?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=-angheight,?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))13. 顏色檢測
在本次例子中實現(xiàn)檢測圖片中的綠色區(qū)域,使用的圖片:
首先是讀取圖片后,轉(zhuǎn)換到 HSV 空間:
接著需要通過 Numpy 設(shè)置綠色像素值的上下范圍區(qū)間:
lower_green?=?np.array([34,?177,?76]) upper_green?=?np.array([255,?255,?255])接著通過 inRange() 方法來判斷輸入圖片中是否包含在設(shè)置后的綠色區(qū)間范圍內(nèi),如果有,那就表示檢測到綠色這種顏色的像素區(qū)域。
完整實現(xiàn)的代碼:
import?cv2 import?numpy?as?npimg?=?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))實現(xiàn)結(jié)果:
14. 去噪
OpenCV 中提供了下面 4 種圖像去噪的方法:
本次例子會用第二種方法:fastNlMeansDenoisingColored()
實現(xiàn)的代碼如下所示:
import?cv2img?=?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()的個參數(shù)分別是:
實現(xiàn)結(jié)果:
15. 檢測圖片的輪廓
輪廓是圖片中將連續(xù)的點連接在一起的曲線,通常檢測輪廓的目的是為了檢測物體。本例中使用的圖片如下:
檢測輪廓的步驟如下:
實現(xiàn)代碼:
import?cv2img?=?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))實現(xiàn)效果:
16. 移除圖片的背景
移除圖片背景的實現(xiàn)思路是這樣的:
本次樣例使用的原圖:
實現(xiàn)代碼:
import?cv2 import?numpy?as?npimg?=?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))實現(xiàn)結(jié)果:
小結(jié)
本文是簡單介紹了基于 opencv 實現(xiàn)的一些圖像處理操作,從基礎(chǔ)的旋轉(zhuǎn),裁剪,調(diào)整大小,到模糊圖片,邊緣檢測,修正歪曲文字,去噪,檢測輪廓等操作,都給出了基礎(chǔ)的實現(xiàn)代碼,如果需要更深入了解,這里推薦:
最后,原文地址:
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
如果覺得本文對你有幫助了,歡迎點贊or在看or分享,謝謝!
精選AI文章
1.??2020年計算機視覺學習指南
2.?是選擇Keras還是PyTorch開始你的深度學習之旅呢?
3.?編寫高效的PyTorch代碼技巧(上)
4.?編寫高效的PyTorch代碼技巧(下)
5.?深度學習算法簡要綜述(上)
6.?深度學習算法簡要綜述(下)
7.?10個實用的機器學習建議
8.?實戰(zhàn)|手把手教你訓練一個基于Keras的多標簽圖像分類器
精選python文章
1.??python數(shù)據(jù)模型
2.?python版代碼整潔之道
3.?快速入門 Jupyter notebook
4.?Jupyter 進階教程
5.?10個高效的pandas技巧
精選教程資源文章
1.?22 款設(shè)計和可視化神經(jīng)網(wǎng)絡(luò)的工具
2.?[資源]推薦一些Python書籍和教程,入門和進階的都有!
3.?[Github項目推薦] 推薦三個助你更好利用Github的工具
4.?Github上的各大高校資料以及國外公開課視頻
5.?GitHub上有哪些比較好的計算機視覺/機器視覺的項目?
歡迎關(guān)注我的微信公眾號--算法猿的成長,或者掃描下方的二維碼,大家一起交流,學習和進步!
?總結(jié)
以上是生活随笔為你收集整理的基于 opencv 的图像处理入门教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 硬件
- 下一篇: 成为优秀程序员应该具备的8个特质