python——opencv入门(一)
1、 OpenCV的結構
和Python一樣,當前的OpenCV也有兩個大版本,OpenCV2和OpenCV3。相比OpenCV2,OpenCV3提供了更強的功能和更多方便的特性。不過考慮到和深度學習框架的兼容性,以及上手安裝的難度,這部分先以2為主進行介紹。
根據功能和需求的不同,OpenCV中的函數接口大體可以分為如下部分:
core:核心模塊,主要包含了OpenCV中最基本的結構(矩陣,點線和形狀等),以及相關的基礎運算/操作。
imgproc:圖像處理模塊,包含和圖像相關的基礎功能(濾波,梯度,改變大小等),以及一些衍生的高級功能(圖像分割,直方圖,形態分析和邊緣/直線提取等)。
highgui:提供了用戶界面和文件讀取的基本函數,比如圖像顯示窗口的生成和控制,圖像/視頻文件的IO等。
如果不考慮視頻應用,以上三個就是最核心和常用的模塊了。針對視頻和一些特別的視覺應用,OpenCV也提供了強勁的支持:
video:用于視頻分析的常用功能,比如光流法(Optical Flow)和目標跟蹤等。
calib3d:三維重建,立體視覺和相機標定等的相關功能。
features2d:二維特征相關的功能,主要是一些不受專利保護的,商業友好的特征點檢測和匹配等功能,比如ORB特征。
object:目標檢測模塊,包含級聯分類和Latent SVM
ml:機器學習算法模塊,包含一些視覺中最常用的傳統機器學習算法。
flann:最近鄰算法庫,Fast Library for Approximate
Nearest Neighbors,用于在多維空間進行聚類和檢索,經常和關鍵點匹配搭配使用。gpu:包含了一些gpu加速的接口,底層的加速是CUDA實現。
photo:計算攝像學(Computational Photography)相關的接口,當然這只是個名字,其實只有圖像修復和降噪而已。
stitching:圖像拼接模塊,有了它可以自己生成全景照片。
nonfree:受到專利保護的一些算法,其實就是SIFT和SURF。
contrib:一些實驗性質的算法,考慮在未來版本中加入的。
legacy:字面是遺產,意思就是廢棄的一些接口,保留是考慮到向下兼容。
ocl:利用OpenCL并行加速的一些接口。
superres:超分辨率模塊,其實就是BTV-L1(Biliteral Total Variation – L1
regularization)算法viz:基礎的3D渲染模塊,其實底層就是著名的3D工具包VTK(Visualization Toolkit)。
從使用的角度來看,和OpenCV2相比,OpenCV3的主要變化是更多的功能和更細化的模塊劃分。
2、python——opencv基礎
2.1 圖像的表示
已知單通道的灰度圖像在計算機中的表示是一個8位無符號整形的矩陣,在oncv的C++代碼中,表示圖像有專門的結構cv::Mat,但python中有numpy這種強大的基礎工具,所以該矩陣就用numpy的array表示,多通道就是紅綠藍(RGB)三通道。
2.2 基本處理
(1)讀取圖像:cv.imread()
可以按照不同模式讀取,一般最常用到的是讀取單通道灰度圖,或者直接默認讀取多通道
(2)儲存圖像:cv.imwrite()
import cv2 color_img=cv2.imread('4.jpg') print(color_img.shape)# 讀取單通道 gray_img=cv2.imread('4.jpg',cv2.IMREAD_GRAYSCALE) print(gray_img.shape)#把單通道圖像保存后,再讀取,仍然是3通道,相當于將單通道復制到3個通道保存 cv2.imwrite('grayscale_4.jpg',gray_img) reload_grayscale=cv2.imread('grayscale_4.jpg') print(reload_grayscale.shape)# 指定jpg質量,范圍從1~100,默認95,值越高畫質越好,文件越大 cv2.imwrite('anglababy.jpg',color_img,(cv2.IMWRITE_JPEG_QUALITY,20))(2)縮放、裁剪、補邊
縮放:im.resize()
裁剪:利用array下標截取實現
(3)色調、明暗、直方圖、Gamma曲線
比如可以通過HSV空間對色調和明暗進行調節。HSV空間是由美國的圖形學專家A. R. Smith提出的一種顏色空間,HSV分別是色調(Hue),飽和度(Saturation)和明度(Value)。在HSV空間中進行調節就避免了直接在RGB空間中調節是還需要考慮三個通道的相關性。OpenCV中H的取值是[0, 180),其他兩個通道的取值都是[0, 256),下面例子接著上面例子代碼,通過HSV空間對圖像進行調整:
import cv2img=cv2.imread('mushroom.jpg') # 通過cv2.cvtcolor把圖像從RGB轉到HSV img_hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)# H空間中,綠色比黃色值高,所以給每個像素+15,黃色的就會變綠 turn_green_hsv=img_hsv.copy() turn_green_hsv[:,:,0]=(turn_green_hsv[:,:,0]+15) turn_green_img=cv2.cvtColor(turn_green_hsv,cv2.COLOR_HSV2BGR)cv2.imshow("turn_green_img",turn_green_img)# 減小飽和度會讓圖像損失鮮艷,變得更灰 colorless_hsv=img_hsv.copy() colorless_hsv[:,:,1]=0.5*colorless_hsv[:,:,1] colorless_img=cv2.cvtColor(colorless_hsv,cv2.COLOR_HSV2BGR) cv2.imshow("colorless_img",colorless_img)# 減小為原來的一半 darker_hsv=img_hsv.copy() darker_hsv[:,:,2]=0.5*darker_hsv[:,:,2] darker_img=cv2.cvtColor(darker_hsv,cv2.COLOR_HSV2BGR) cv2.imshow("darker_img",darker_img)cv2.waitKey(0)直方圖:方便對圖像的像素值分布了解更清晰,低的像素值表示暗的部分,高的值表示亮度大的部分,但是顯示的時候可能就出現了暗部細節不足或者亮部細節丟失的情況。
Gamma變換:提升暗部細節,Gamma變換是矯正相機直接成像和人眼感受圖像差別的一種常用手段,簡單來說就是通過非線性變換讓圖像從對曝光強度的線性響應變得更接近人眼感受到的響應。
import numpy as np import cv2 import matplotlib.pylab as plt from mpl_toolkits.mplot3d import Axes3Dimg=cv2.imread('4.jpg')# 分通道計算每個通道的直方圖 hist_b=cv2.calcHist([img],[0],None,[256],[0,256]) hist_g=cv2.calcHist([img],[1],None,[256],[0,256]) hist_r=cv2.calcHist([img],[2],None,[256],[0,256])# Gamma變換的函數 def gamma_trans(img,gamma):# 先歸一化到1,之后利用gamma作為指數求出新值,再還原gamma_table=[np.power(x/255.0,gamma)*255.0 for x in range(256)]gamma_table=np.round(np.array(gamma_table)).astype(np.uint8)# 用opencv的查表函數實現該映射return cv2.LUT(img,gamma_table)# 執行Gamma變換,小于1的值讓暗細節大量提升,同時亮部細節少量提升 img_corrected=gamma_trans(img,0.5) cv2.imshow("img",img) cv2.imshow("img_corrected",img_corrected) # cv2.waitKey(0)# 分通道計算Gamma矯正后的直方圖 hist_b_corrected=cv2.calcHist([img_corrected],[0],None,[256],[0,256]) hist_g_corrected=cv2.calcHist([img_corrected],[1],None,[256],[0,256]) hist_r_corrected=cv2.calcHist([img_corrected],[2],None,[256],[0,256])# 直方圖可視化fig=plt.figure() pix_hists=[[hist_b,hist_g,hist_r],[hist_b_corrected,hist_g_corrected,hist_r_corrected] ] pix_vals=range(256) for sub_plt,pix_hist in zip([121,122],pix_hists):ax=fig.add_subplot(sub_plt,projection='3d')for c,z,channel_hist in zip(['b','g','r'],[20,10,0],pix_hist):cs=[c]*256ax.bar(pix_vals,channel_hist,zs=z,zdir='y',color=cs,alpha=0.618,edgecolor='none',lw=0)ax.set_xlabel('Pixel Values')ax.set_xlim([0,256])ax.set_ylabel('Channels')ax.set_zlabel('Counts')plt.show()
(4)仿射變換
圖像的仿射變換涉及到圖像的形狀位置角度的變化,是深度學習預處理中常到的功能,在此簡單回顧一下。仿射變換具體到圖像中的應用,主要是對圖像的縮放,旋轉,剪切,翻轉和平移的組合。在OpenCV中,仿射變換的矩陣是一個2×3的矩陣,其中左邊的2×2子矩陣是線性變換矩陣,右邊的2×1的兩項是平移項:
對于圖像上的任一位置(x,y),仿射變換執行的是如下的操作:
需要注意的是,對于圖像而言,寬度方向是x,高度方向是y,坐標的順序和圖像像素對應下標一致。所以原點的位置不是左下角而是右上角,y的方向也不是向上,而是向下。在OpenCV中實現仿射變換是通過仿射變換矩陣和cv2.warpAffine()這個函數:
總結
以上是生活随笔為你收集整理的python——opencv入门(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pycharm上传代码到github
- 下一篇: 排序算法python版本