OpenCV与图像处理学习一——图像基础知识、读入、显示、保存图像、灰度转化、通道分离与合并
OpenCV與圖像處理學習一——圖像基礎知識、讀入、顯示、保存圖像、灰度轉化、通道分離與合并
- 一、圖像基礎知識
- 1.1 數字圖像的概念
- 1.2 數字圖像的應用
- 1.3 OpenCV介紹
- 二、圖像屬性
- 2.1 圖像格式
- 2.2 圖像尺寸
- 2.2.1 讀入圖像
- 2.2.2 顯示圖像
- 2.2.3 保存圖像
- 2.3 圖像分辨率和通道數
- 2.3.1 灰度轉化
- 2.3.2 RGB與BGR轉化
- 2.3.3 通道分離
- 2.3.4 通道合并
圖像處理與OpenCV作為CV方向的基礎,在正式系統地學習論文之前,有必要對其進行系統的學習。而OpenCV作為使用最為廣泛的圖像處理工具包,這里將其作為學習的工具,因為較為熟悉python,所以使用OpenCV的python接口來完成代碼。
圖像處理與OpenCV的學習主要包括五個部分:
- 圖像基礎知識
- 圖像處理
- 圖像分割
- 圖像特征與目標檢測
- 運動目標識別(視頻)
ps:OpenCV-python版的官方文檔:https://docs.opencv.org/4.1.2/d6/d00/tutorial_py_root.html
一、圖像基礎知識
1.1 數字圖像的概念
數字圖像又稱為數碼圖像或數位圖像,是二維圖像用有限數字數值像素的表示,由數組成矩陣來表示。下圖是一個例子:
我們看見的圖像在計算機中其實是由一個個像素組成的,每個像素有其具體數值。
也可以理解為一個二維函數 f(x,y),其中x和y是空間(平面)坐標,而在任意坐標處幅值 f 稱為圖像在該點處的強度或灰度。
1.2 數字圖像的應用
圖像處理、機器視覺與人工智能的關系:
- 圖像處理主要研究二維檢測,處理一個圖像或一組圖像之間的相互轉換的過程,包括圖像濾波、圖像識別、圖像分割等問題。
- 機器視覺主要研究映射到單幅或多幅圖像上的三維場景,從圖像中提取抽象的語義信息,實現圖像理解是CV的終極目標。
- 人工智能在計算機視覺上的目標就是解決像素值和語義之間的關系,主要的問題有圖片檢測、圖片識別、圖片分割和檢索等。
1.3 OpenCV介紹
OpenCV于1999年由Intel建立;是一個開源發行的跨平臺計算機視覺庫;支持的操作系統有Linux、Windows、Android、macOS。
由C函數與少量C++類構成,支持Python、Java、MATLAB等接口,是數字圖像處理和CV領域最常見的工具包,是學習、科研、企業項目的好幫手。
OpenCV的安裝(默認python已經安裝):
打開命令行,輸入以下命令,即可自動下載安裝:
pip install opencv-contrib-python二、圖像屬性
2.1 圖像格式
常見的圖像格式如下所示:
2.2 圖像尺寸
圖像尺寸的長度和寬度是以像素為單位的,比如下面圖片的尺寸是240×150,這個數字的單位就是像素。那么像素具體是什么含義?
像素pixel:
像素是數碼影像最基本的單位。1.1那張圖中數字化后圖片變成了一個個小格子組成的大矩陣,每個小格子就是一個像素,它里面會有一個值,灰度像素點的值的范圍在0~255之間,0表示黑色,255表示白色,其他值是介于黑白之間的不同灰;
如果是彩色圖,會需要用到紅、綠、藍三個通道的二維矩陣來表示,在每個通道中,每個值也介于0~255之間,0表示相應的基色,而255表示相應基色在該像素中取得的最大值。
2.2.1 讀入圖像
cv2.imread( filename[, flags] )參數:第一個參數為讀入圖像的路徑;第二個則是讀取的方式,常見方式有:
- cv2.IMREAD_COLOR:默認方式,讀取彩色圖像,也可以用 1 來表示。
- cv2.IMREAD_GRAYSCALE:讀取圖像為灰度圖,也可以用 0 來表示。
- cv2.IMREAD_UNCHANGED:讀取彩色圖,并且包括透明度通道,也可以用 -1 來表示。
舉例:
# 導入opencv的python版本依賴庫cv2 import cv2 # 使用opencv中imread函數讀取圖片, # 0代表灰度圖形式打開,1代表彩色形式打開 img = cv2.imread('split.jpg', 1) print(img.shape)輸出為這張圖片的尺寸(shape):
(459, 571, 3)2.2.2 顯示圖像
cv2.imshow( winname, mat )參數:第一個參數為窗口的名字(顯示圖片必須先有一個窗口),第二個參數為圖像變量名。
舉例:
# 導入opencv的python版本依賴庫cv2 import cv2 # 使用opencv中imread函數讀取圖片, # 0代表灰度圖形式打開,1代表彩色形式打開 img = cv2.imread('split.jpg', 1) print(img.shape) # print(img)cv2.imshow('photo', img) k = cv2.waitKey(0) if k == 27: # 輸入ESC鍵退出cv2.destroyAllWindows() elif k == ord('s'): # 輸入S鍵保存圖片并退出cv2.imwrite('split_.jpg', img) cv2.destroyAllWindows()其中cv2.waitKey()函數是一個鍵盤綁定函數,單位為毫秒,即程序等待鍵盤輸入多少毫秒,在這等待的時間內從鍵盤輸入的鍵值會賦給k,然后k去進行下一步程序,如cv2.waitKey(1000)就是等待1s;如果參數值為0,則表示一直等待直到鍵盤有輸入。
另外,cv2.destroyAllWindows()函數表示刪除窗口,默認刪除所有窗口,參數為待刪窗口名。
2.2.3 保存圖像
cv2.imwrite( filename, img[, params] )參數:第一個參數為希望保存成的圖像名(包括格式(后綴)),第二個參數為待寫入的圖像變量名。
2.2.2的代碼已經給出了舉例。
2.3 圖像分辨率和通道數
分辨率是指單位長度中所表達或截取的像素數目。每英寸圖像內的像素點數,單位是像素每英寸(ppi)。圖像的分辨率越高,像素點密度越高,圖像越清晰。
通道數是指圖像的位深度,描述圖像中每個pixel數值所占的二進制位數。位深度越大則圖像能表示的顏色數越多,色彩就越豐富。有以下幾種位深度:
- 8位:單通道圖像,也就是灰度圖,灰度值取值種類為2 ^ 8 = 256種,即0~255。
- 24位:三通道,彩色圖像,每個通道都有8位。
- 32位:三通道彩色圖像加上透明度Alpha通道。
2.3.1 灰度轉化
目的:將彩色圖轉化為灰度圖。
公式:
- 3通道彩圖->1通道灰圖:GRAY = B * 0.114 + G * 0.587 + R * 0.299
- 1通道灰圖->3通道灰圖:R = G = B = GRAY;A = 0
函數為:
cv2.cvtColor( src, code[, dst[, dstCn]] )參數:第一個參數就是待轉化的圖像變量;第二個參數是轉換模式,OpenCV有二百多種模式轉換,具體可以通過以下代碼查看:
>>> import cv2 as cv >>> flags = [i for i in dir(cv) if i.startswith('COLOR_')] >>> print( flags )輸出如下:
['COLOR_BAYER_BG2BGR', 'COLOR_BAYER_BG2BGRA', 'COLOR_BAYER_BG2BGR_EA', 'COLOR_BAYER_BG2BGR_VNG', 'COLOR_BAYER_BG2GRAY', 'COLOR_BAYER_BG2RGB', 'COLOR_BAYER_BG2RGBA', 'COLOR_BAYER_BG2RGB_EA', 'COLOR_BAYER_BG2RGB_VNG', 'COLOR_BAYER_GB2BGR', 'COLOR_BAYER_GB2BGRA', 'COLOR_BAYER_GB2BGR_EA', 'COLOR_BAYER_GB2BGR_VNG', 'COLOR_BAYER_GB2GRAY', 'COLOR_BAYER_GB2RGB', 'COLOR_BAYER_GB2RGBA', 'COLOR_BAYER_GB2RGB_EA', 'COLOR_BAYER_GB2RGB_VNG', 'COLOR_BAYER_GR2BGR', 'COLOR_BAYER_GR2BGRA', 'COLOR_BAYER_GR2BGR_EA', 'COLOR_BAYER_GR2BGR_VNG', 'COLOR_BAYER_GR2GRAY', 'COLOR_BAYER_GR2RGB', 'COLOR_BAYER_GR2RGBA', 'COLOR_BAYER_GR2RGB_EA', 'COLOR_BAYER_GR2RGB_VNG', 'COLOR_BAYER_RG2BGR', 'COLOR_BAYER_RG2BGRA', 'COLOR_BAYER_RG2BGR_EA', 'COLOR_BAYER_RG2BGR_VNG', 'COLOR_BAYER_RG2GRAY', 'COLOR_BAYER_RG2RGB', 'COLOR_BAYER_RG2RGBA', 'COLOR_BAYER_RG2RGB_EA', 'COLOR_BAYER_RG2RGB_VNG', 'COLOR_BGR2BGR555', 'COLOR_BGR2BGR565', 'COLOR_BGR2BGRA', 'COLOR_BGR2GRAY', 'COLOR_BGR2HLS', 'COLOR_BGR2HLS_FULL', 'COLOR_BGR2HSV', 'COLOR_BGR2HSV_FULL', 'COLOR_BGR2LAB', 'COLOR_BGR2LUV', 'COLOR_BGR2Lab', 'COLOR_BGR2Luv', 'COLOR_BGR2RGB', 'COLOR_BGR2RGBA', 'COLOR_BGR2XYZ', 'COLOR_BGR2YCR_CB', 'COLOR_BGR2YCrCb', 'COLOR_BGR2YUV', 'COLOR_BGR2YUV_I420', 'COLOR_BGR2YUV_IYUV', 'COLOR_BGR2YUV_YV12', 'COLOR_BGR5552BGR', 'COLOR_BGR5552BGRA', 'COLOR_BGR5552GRAY', 'COLOR_BGR5552RGB', 'COLOR_BGR5552RGBA', 'COLOR_BGR5652BGR', 'COLOR_BGR5652BGRA', 'COLOR_BGR5652GRAY', 'COLOR_BGR5652RGB', 'COLOR_BGR5652RGBA', 'COLOR_BGRA2BGR', 'COLOR_BGRA2BGR555', 'COLOR_BGRA2BGR565', 'COLOR_BGRA2GRAY', 'COLOR_BGRA2RGB', 'COLOR_BGRA2RGBA', 'COLOR_BGRA2YUV_I420', 'COLOR_BGRA2YUV_IYUV', 'COLOR_BGRA2YUV_YV12', 'COLOR_BayerBG2BGR', 'COLOR_BayerBG2BGRA', 'COLOR_BayerBG2BGR_EA', 'COLOR_BayerBG2BGR_VNG', 'COLOR_BayerBG2GRAY', 'COLOR_BayerBG2RGB', 'COLOR_BayerBG2RGBA', 'COLOR_BayerBG2RGB_EA', 'COLOR_BayerBG2RGB_VNG', 'COLOR_BayerGB2BGR', 'COLOR_BayerGB2BGRA', 'COLOR_BayerGB2BGR_EA', 'COLOR_BayerGB2BGR_VNG', 'COLOR_BayerGB2GRAY', 'COLOR_BayerGB2RGB', 'COLOR_BayerGB2RGBA', 'COLOR_BayerGB2RGB_EA', 'COLOR_BayerGB2RGB_VNG', 'COLOR_BayerGR2BGR', 'COLOR_BayerGR2BGRA', 'COLOR_BayerGR2BGR_EA', 'COLOR_BayerGR2BGR_VNG', 'COLOR_BayerGR2GRAY', 'COLOR_BayerGR2RGB', 'COLOR_BayerGR2RGBA', 'COLOR_BayerGR2RGB_EA', 'COLOR_BayerGR2RGB_VNG', 'COLOR_BayerRG2BGR', 'COLOR_BayerRG2BGRA', 'COLOR_BayerRG2BGR_EA', 'COLOR_BayerRG2BGR_VNG', 'COLOR_BayerRG2GRAY', 'COLOR_BayerRG2RGB', 'COLOR_BayerRG2RGBA', 'COLOR_BayerRG2RGB_EA', 'COLOR_BayerRG2RGB_VNG', 'COLOR_COLORCVT_MAX', 'COLOR_GRAY2BGR', 'COLOR_GRAY2BGR555', 'COLOR_GRAY2BGR565', 'COLOR_GRAY2BGRA', 'COLOR_GRAY2RGB', 'COLOR_GRAY2RGBA', 'COLOR_HLS2BGR', 'COLOR_HLS2BGR_FULL', 'COLOR_HLS2RGB', 'COLOR_HLS2RGB_FULL', 'COLOR_HSV2BGR', 'COLOR_HSV2BGR_FULL', 'COLOR_HSV2RGB', 'COLOR_HSV2RGB_FULL', 'COLOR_LAB2BGR', 'COLOR_LAB2LBGR', 'COLOR_LAB2LRGB', 'COLOR_LAB2RGB', 'COLOR_LBGR2LAB', 'COLOR_LBGR2LUV', 'COLOR_LBGR2Lab', 'COLOR_LBGR2Luv', 'COLOR_LRGB2LAB', 'COLOR_LRGB2LUV', 'COLOR_LRGB2Lab', 'COLOR_LRGB2Luv', 'COLOR_LUV2BGR', 'COLOR_LUV2LBGR', 'COLOR_LUV2LRGB', 'COLOR_LUV2RGB', 'COLOR_Lab2BGR', 'COLOR_Lab2LBGR', 'COLOR_Lab2LRGB', 'COLOR_Lab2RGB', 'COLOR_Luv2BGR', 'COLOR_Luv2LBGR', 'COLOR_Luv2LRGB', 'COLOR_Luv2RGB', 'COLOR_M_RGBA2RGBA', 'COLOR_RGB2BGR', 'COLOR_RGB2BGR555', 'COLOR_RGB2BGR565', 'COLOR_RGB2BGRA', 'COLOR_RGB2GRAY', 'COLOR_RGB2HLS', 'COLOR_RGB2HLS_FULL', 'COLOR_RGB2HSV', 'COLOR_RGB2HSV_FULL', 'COLOR_RGB2LAB', 'COLOR_RGB2LUV', 'COLOR_RGB2Lab', 'COLOR_RGB2Luv', 'COLOR_RGB2RGBA', 'COLOR_RGB2XYZ', 'COLOR_RGB2YCR_CB', 'COLOR_RGB2YCrCb', 'COLOR_RGB2YUV', 'COLOR_RGB2YUV_I420', 'COLOR_RGB2YUV_IYUV', 'COLOR_RGB2YUV_YV12', 'COLOR_RGBA2BGR', 'COLOR_RGBA2BGR555', 'COLOR_RGBA2BGR565', 'COLOR_RGBA2BGRA', 'COLOR_RGBA2GRAY', 'COLOR_RGBA2M_RGBA', 'COLOR_RGBA2RGB', 'COLOR_RGBA2YUV_I420', 'COLOR_RGBA2YUV_IYUV', 'COLOR_RGBA2YUV_YV12', 'COLOR_RGBA2mRGBA', 'COLOR_XYZ2BGR', 'COLOR_XYZ2RGB', 'COLOR_YCR_CB2BGR', 'COLOR_YCR_CB2RGB', 'COLOR_YCrCb2BGR', 'COLOR_YCrCb2RGB', 'COLOR_YUV2BGR', 'COLOR_YUV2BGRA_I420', 'COLOR_YUV2BGRA_IYUV', 'COLOR_YUV2BGRA_NV12', 'COLOR_YUV2BGRA_NV21', 'COLOR_YUV2BGRA_UYNV', 'COLOR_YUV2BGRA_UYVY', 'COLOR_YUV2BGRA_Y422', 'COLOR_YUV2BGRA_YUNV', 'COLOR_YUV2BGRA_YUY2', 'COLOR_YUV2BGRA_YUYV', 'COLOR_YUV2BGRA_YV12', 'COLOR_YUV2BGRA_YVYU', 'COLOR_YUV2BGR_I420', 'COLOR_YUV2BGR_IYUV', 'COLOR_YUV2BGR_NV12', 'COLOR_YUV2BGR_NV21', 'COLOR_YUV2BGR_UYNV', 'COLOR_YUV2BGR_UYVY', 'COLOR_YUV2BGR_Y422', 'COLOR_YUV2BGR_YUNV', 'COLOR_YUV2BGR_YUY2', 'COLOR_YUV2BGR_YUYV', 'COLOR_YUV2BGR_YV12', 'COLOR_YUV2BGR_YVYU', 'COLOR_YUV2GRAY_420', 'COLOR_YUV2GRAY_I420', 'COLOR_YUV2GRAY_IYUV', 'COLOR_YUV2GRAY_NV12', 'COLOR_YUV2GRAY_NV21', 'COLOR_YUV2GRAY_UYNV', 'COLOR_YUV2GRAY_UYVY', 'COLOR_YUV2GRAY_Y422', 'COLOR_YUV2GRAY_YUNV', 'COLOR_YUV2GRAY_YUY2', 'COLOR_YUV2GRAY_YUYV', 'COLOR_YUV2GRAY_YV12', 'COLOR_YUV2GRAY_YVYU', 'COLOR_YUV2RGB', 'COLOR_YUV2RGBA_I420', 'COLOR_YUV2RGBA_IYUV', 'COLOR_YUV2RGBA_NV12', 'COLOR_YUV2RGBA_NV21', 'COLOR_YUV2RGBA_UYNV', 'COLOR_YUV2RGBA_UYVY', 'COLOR_YUV2RGBA_Y422', 'COLOR_YUV2RGBA_YUNV', 'COLOR_YUV2RGBA_YUY2', 'COLOR_YUV2RGBA_YUYV', 'COLOR_YUV2RGBA_YV12', 'COLOR_YUV2RGBA_YVYU', 'COLOR_YUV2RGB_I420', 'COLOR_YUV2RGB_IYUV', 'COLOR_YUV2RGB_NV12', 'COLOR_YUV2RGB_NV21', 'COLOR_YUV2RGB_UYNV', 'COLOR_YUV2RGB_UYVY', 'COLOR_YUV2RGB_Y422', 'COLOR_YUV2RGB_YUNV', 'COLOR_YUV2RGB_YUY2', 'COLOR_YUV2RGB_YUYV', 'COLOR_YUV2RGB_YV12', 'COLOR_YUV2RGB_YVYU', 'COLOR_YUV420P2BGR', 'COLOR_YUV420P2BGRA', 'COLOR_YUV420P2GRAY', 'COLOR_YUV420P2RGB', 'COLOR_YUV420P2RGBA', 'COLOR_YUV420SP2BGR', 'COLOR_YUV420SP2BGRA', 'COLOR_YUV420SP2GRAY', 'COLOR_YUV420SP2RGB', 'COLOR_YUV420SP2RGBA', 'COLOR_YUV420p2BGR', 'COLOR_YUV420p2BGRA', 'COLOR_YUV420p2GRAY', 'COLOR_YUV420p2RGB', 'COLOR_YUV420p2RGBA', 'COLOR_YUV420sp2BGR', 'COLOR_YUV420sp2BGRA', 'COLOR_YUV420sp2GRAY', 'COLOR_YUV420sp2RGB', 'COLOR_YUV420sp2RGBA', 'COLOR_mRGBA2RGBA']那么這里的灰度轉化需要用到的是cv2.COLOR_BGR2GRAY和cv2.COLOR_GRAY2BGR。
舉例如下:
# 導入opencv import cv2 # 讀入原始圖像,使用cv2.IMREAD_UNCHANGED img = cv2.imread("girl.jpg", cv2.IMREAD_UNCHANGED) # 查看打印圖像的shape shape = img.shape print(shape) # 判斷通道數是否為3通道或4通道 if shape[2] == 3 or shape[2] == 4 :# 將彩色圖轉化為單通道圖img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)cv2.imshow("gray_image", img_gray) cv2.imshow("image", img) cv2.waitKey(0) cv2.destroyAllWindows()顯示出來的原圖與灰度化之后的圖為:
這里的灰度圖是單通道的,若將此時的img_gray 再通過cv2.COLOR_GRAY2BGR轉為三通道的圖,它將還是灰度圖,只是通道數變成了三個,三通道每個像素上的B、G、R值都相等,且等于img_gray 的那個像素,代碼如下所示:
效果如圖所示:
視覺上細看還是有些許不同,我們搞清楚它們在計算機內的區別就行,再看下原圖、單通道灰度圖、三通道灰度圖的尺寸區別:
2.3.2 RGB與BGR轉化
方法一:用OpenCV自帶的方法
# 導入opencv import cv2 # 讀入圖 img = cv2.imread("dark2.jpg", cv2.IMREAD_COLOR) cv2.imshow("Origin", img) img_cv_method = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) cv2.imshow("After transform", img_cv_method)cv2.waitKey(0) cv2.destroyAllWindows()方法二:用numpy轉換,本質就是互換B和R通道,所以將方法一的代碼中的cvtColor函數的那一行替換為
img_cv_method = img[:, :, ::-1]效果是一樣的,得到的原圖和轉換之后的圖的顯示如下所示:
2.3.3 通道分離
目的:將彩色圖像分成B、G、R三個單通道圖像,方便我們對BGR三個通道分別操作。
函數:
cv.split( m[, mv] )參數:待分離通道的圖像。
舉例:
# 加載opencv import cv2 src = cv2.imread('split.jpg') cv2.imshow('before', src) # 調用通道分離 b, g, r = cv2.split(src) # 三通道分別顯示 cv2.imshow('blue', b) cv2.imshow('green', g) cv2.imshow('red', r) cv2.waitKey(0) cv2.destroyAllWindows()結果如下所示:
分離出來的每個通道都是一個灰度圖。如果我們想看它們是對應通道的顏色,可以用下面的代碼:
效果如下所示:
這里我們可以看出,單通道是沒有顏色的,只有數值,R、G、B顏色要放在三通道中才能顯示出來。
2.3.4 通道合并
目的:三個單獨的通道合并為一個彩圖。
函數:
cv.merge( mv[, dst] )參數:待合并的通道數,以list形式輸入。
舉例:
#加載opencv import cv2 src=cv2.imread('split.jpg') cv2.imshow('before',src) #調用通道分離 b,g,r=cv2.split(src) #將Blue通道數值修改為0 b[:] = 0 #合并修改后的通道 img_merge=cv2.merge([b,g,r]) cv2.imshow('merge',img_merge) cv2.waitKey(0) cv2.destroyAllWindows()結果如下所示:
總結
以上是生活随笔為你收集整理的OpenCV与图像处理学习一——图像基础知识、读入、显示、保存图像、灰度转化、通道分离与合并的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: duilib环境配置以及简单入门介绍
- 下一篇: 矩阵转置函数——指针自增的陷阱