OpenCV進行圖像處理很方便
圖像分類
二值圖像(1/0)、灰度圖像(純黑 0-255 純白)、RGB圖像(RGB三原色 R0-255 | G0-255 | B0-255 即一個像素三個值)
opencv 里表示彩色圖像順序是BGR,與一般順序RGB是不一樣的,可以轉換成RGB再進行處理
1、圖形讀入(該顏色表示不是必須的)
retval = cv2.imread(完整文件名[,顯示控制參數]) 參數 : cv.IMREAD_UNCHANGED(不改變)、cv.IMREAD_GRAYSCALE(以灰度形式顯示)、cv.IMREAD_COLOR(以彩色形式顯示)
img=cv2.imread("d:\\image.jpg")
2、顯示圖形
None = cv2.imshow(窗口名,圖像名) (注意不要寫中文,中文不顯示)
cv2.imshow("demo",image)
retval = cv2.waitKey( [,delay]) delay : delay>0 等待delay毫秒,delay<0 等待鍵盤單擊,delay=0,無限等待
cv2.waitKey(0)
cv2.destroyAllWindows() 刪除所有窗口,從內存里清空,銷毀數據
3、保存圖像
retval = cv2.imwrite(文件地址,文件名)
cv2.imwrite('D:\\test.jpg',img)
4、讀取像素
返回值=圖像(位置參數)
灰度圖像,返回灰度值
p=img[88,142] (返回第88行,142列那個像素)
print(p)
BGR圖像,返回值為B、G、R的值(可以分別打印每個通道的值進行查看,0通道為B,1通道為G,2通道為R)
blue=img[78,125,0]
green=img[78,125,1]
red=img[78,125,2]
print(blue)(打印藍色通道的值)
不指定通道會打印三個值
p=img[78,125]
print(p)
5、修改像素
像素=新值
灰度圖像
img[88,99]=255
BGR圖像,分通道賦值
img[88,99,0]=255
直接修改
img[88,99]=[255,255,255]
6、使用numpy進行像素處理(不用opencv)
讀取像素
返回值=圖像.item(位置參數)
灰度圖像
p=img.item(88,142)
print(p)
BGR圖像,像素點上有三個值,根據下標不同分別取得三個通道的值
blue=img.item(78,125,0)
修改像素
圖像名.itemset(位置,新值)
灰度圖像 img.itemset((88,99),255)第88行99列的值改成255
BGR圖像 img.itemset((88,99,0),255)修改特定的通道的值
7、獲取圖像屬性
shape可以獲取圖像的形狀,返回包含行數,列數,通道數的元組
灰度圖像 返回行數,列數 | 彩色圖像 返回行數,列數,通道數
import cv2
img1=cv2.imread('灰度圖像/彩色圖像')
print(img1.shape)
size可以獲取圖像的像素數目
灰度圖像 行數*列數 | 彩色圖像 行數*列數*通道數
import cv2
img1=cv2.imread('圖像名')
print(img1.size)
dtype返回的是圖像的數據類型
import cv2
img1=cv2.imread('圖像名稱')
print(img1.dtype)
##uint8
8、圖像ROI
ROI(region of interest),感興趣區域
從被處理的圖像以方框、圓、橢圓、不規則多邊形等方式勾勒出需要處理的區域。
可以通過各種算子(Operator)和函數來求得感興趣區域ROI,並進行圖像的下一步處理。
import cv2
img1=cv2.imread('圖像名稱')
face=img1[200:400,200:400] 引用圖像200行到400,和200列到400列部分區域,取名face
img1[200:400,600:800]=face 可以使用face,比如將另一部分區域等於face
9、通道的拆分
import cv2
img1=cv2.imread('圖像名稱')
b,g,r=cv2.split(img1)
cv2.imshow("blue",b)
cv2.imshow("green",g)
cv2.imshow("red",r)
只拆分一個通道,下標0,1,2分別表示B,G,R通道
b=cv2.split(a)[0]
10、通道的合並
m=cv2.merge([b,g,r]) 注意b,g,r的順序
紅色通道與都是0的另外兩個通道合並,得到的圖像是紅色的
import cv2
import numpy as np
a = cv2.imread("image\lena.png")
rows.cols.chn=a.shape
b = np.zeros((rows,cols), dtype=a.dtype)
g = np.zeros((rows,cols), dtype=a.dtype)
r = cv2.split(a)[2]
m = cv2.merge([b,g,r])
11、圖像加法運算
參與運算的圖像大小、類型必須一致
numpy加法,不太自然,多的疊加的部分是黑的
取模加法,運算方式:結果 = 圖像1 + 圖像2 ---> 像素值<=255 圖像1+圖像2 ---> 圖像值>255 結果對255取模
100+58=158 255+58= (255+58)%255 = 58
二進制 十進制
0000 0000 0
0000 0001 1
...... ......
1111 1110 254
1111 1111 255
opencv加法,更自然,多的疊加的部分是白的
飽和運算,運算方式:結果 = cv2.add(圖像1,圖像2) ---> 像素值<=255 圖像1+圖像2 ---> 圖像值>255 取值255
100+58=158 255+58= 255
12、圖像融合
圖像融合:結果圖像=圖像1*系數1+圖像2*系數2+亮度調節量
img=img1*0.3+img2*0.7+18
圖像相加相當於兩個圖像權重系數是一樣的,都是1,亮度調節值是0
函數addWeighted
dst = cv.addWeighted(src1,alpha,src2,beta,gamma)
dst = src1*alpha + src2*beta + gamma; 運算公式 參數gamma(亮度調節值)不能省略
13、圖像類型轉換
OpenCV提供了200多種不同類型之間的轉換
彩色轉灰度 b = cv2.cvtColor(a,cv2.COLOR_BGR2GRAY) 第一個參數a是原圖像,第二個參數是轉換的具體類型
BGR轉RGB b = cv2.cvtColor(a,cv2.COLOR_BGR2RGB)
灰度轉BGR b = cv2.cvtColor(a,cv2.COLOR_GRAY2BGR)
14、圖像縮放
語法格式
dst = cv2.resize(src ,dsize[ ,dst[ ,fx[ ,fy[ ,interpolation]]]]) src 原始圖像 dsize 縮放大小 fx, fy 縮放大小 (一般沒有dsize時使用,fx水平方向上的縮放,如果fx>1就是放大,fx<1縮小,=1表示不變)
b = cv2.resize(a,(200,122)) 200,122分別表示圖像的列 和 行
b = cv2.resize(a,None,fx=0.5,fy=0.7)
b = cv2.resize(a, (round(cols*0.5), round(rows*1.2))) 列乘以比例后不一定是整數,但是我們說多少列,列肯定是整數,所以對進行計算的列四舍五入round,讓其是整數的列
15、圖像翻轉
dst = cv2.flip(src, flipCode) src原圖像 ,flipCode以哪種模式進行翻轉
三種翻轉方式, 其一左翻右 ,即以y軸為對稱軸進行左右翻轉 flipCode>0 ,另一種以x為對稱軸進行上下翻轉 flipCode=0,還有一種,翻轉兩次,先以x軸為對稱軸上下翻轉,再以y軸為對稱軸左右翻轉 flipCode<0
dst = cv2.flip( src , 1)
16、閾值分割
二進制閾值化 Threshold Binary
先要選定一個特定的閾值量,比如:127
新的閾值產生規則為:大於等於127的像素點的灰度值設定為最大值(如8位灰度值最大為255)
灰度值小於127的像素點的灰度值設定為0,即最小值
dst ( x, y ) = { maxVal if src( x, y ) > thresh
0 otherwise
反二進制閾值化 Threshold Binary,Inverted
與二進制閾值化相反,得到的是其反色的圖
大於閾值的設定為0,小於該閾值的設定為255
dst ( x, y ) = { 0 if src( x, y ) > thresh
maxVal otherwise
截斷閾值化 Truncate
把比閾值大的像素都處理成閾值,小於該閾值的保持不變。不存在比閾值大的像素值了
dst ( x, y ) = { threshold if src( x, y ) > thresh
src( x, y ) otherwise
反 閾值化為0 Threshold to Zero, Inverted
大於等於閾值的像素處理為0,小於該閾值的像素點值保持不變
dst ( x, y ) = { 0 if src( x, y ) > thresh
src( x, y ) otherwise
閾值化為0 Threshold to Zero
某像素點的值比閾值大,保持不變,如果比閾值小或等於閾值,則處理為0
dst ( x, y ) = { src( x, y ) if src( x, y ) > thresh
0 otherwise
17、函數 threshold 及實現
retval, dst = cv2.threshold( src ,thresh ,maxval ,type)
retval, 閾值(與threshold是一致的) dst, 處理結果圖像 src 源圖像 threshold 閾值(一般是128) maxval 最大值(1也可以255) type 類型
二進制閾值化 cv2.THRESH_BINARY 把亮的處理為白色,暗的處理為黑色
r, b = cv2.threshold(a ,127 ,255 ,cv2.THRESH_BINARY)
反二進制閾值化 cv2.THRESH_BINARY_INV 把亮的處理為黑色,暗的處理為白色,與二進制閾值化是反色的
截斷閾值化 cv2.THRESH_TRUNC 把比較亮的都處理為閾值,整體暗了
反閾值化為0 cv2.THRESH_TOZERO_INV 把比較亮的處理為0,暗一些的像素點不變
閾值化為0 cv2.THRESH_TOZERO 把比較暗的像素點處理為0,比較亮的不變
18、圖像平滑,均值濾波
任意一點的像素值,都是周圍N*N個像素值的均值
5行5列中心點的像素新值=該5行5列像素值之和除25
核 進行均值濾波時要指定的參數,
針對原始圖像內的像素點,逐個采用核進行處理,得到結果圖像
上述5行5列的核是 5行5列個1/25
1 1 1 1 1
1 1 1 1 1 1
K = — [ 1 1 1 1 1 ]
25 1 1 1 1 1
1 1 1 1 1
函數 blur
處理結果 = cv2.blur(原始圖像,核大小)
核大小:以(寬度,高度)形式表示的元組,上面核大小:(5, 5)
核大小:(3, 3) 表示3行3列,對應如下
1 1 1 1
K = — [ 1 1 1 ]
9 1 1 1
r=cv2.blur(o, (5, 5) )
能平滑椒鹽攻擊,每個點都是周圍值的均值
19、圖像平滑,方框濾波
函數boxFilter
處理結果=cv2.boxFilter(原始圖像,目標圖像深度,核大小,normalize屬性)
目標圖像深度:Int類型的目標圖像深度。通常使用“-1”表示與原始圖像一致。
normalize屬性(歸一化屬性):是否對目標圖像進行歸一化處理。
1 1 ... 1
K = — [ ... ... ... ]
a 1 ... 1
a = { 1/(width * height) normalize = true 與均值濾波相同
1 normalize = false 實際上是求和,很容易發生溢出
r = cv2.boxFilter( o, -1, (5, 5), normalize=1) 等於1表示要進行歸一化處理,與均值濾波相同
r = cv2.boxFilter( o, -1, (5, 5)) 省略掉相當於true,進行歸一化處理
r = cv2.boxFilter( o, -1, (5, 5), normalize=0) 相當於false,表示不進行歸一化處理,求和,目標圖像變成白色的
9
20、圖像平滑,高斯濾波
讓臨近的像素具有更高的重要度。對周圍像素計算加權平均值,較近的像素具有較大的權重值。與均值濾波不同之處是,離中心點越近權重越大,離中心點越遠,權重越小。
函數 GaussianBlur
dst = cv2.GaussianBlur( src, ksize, sigmaX)
src,原始圖像,要處理的源圖像 ; ksize,核大小,必須是奇數(N,N) ; sigmaX,X方向方差,控制權重
sigmaX=0就可以了,它會根據核的大小自己去算出方差
sigmaX=0時:sigma = 0.3*( (ksize-1)*0.5 - 1 ) + 0.8
y的方差與x的方差保持一致
r=cv2.GaussianBlur(o,(5,5),0)
安裝opencv(未驗證)
sudo apt-get install libcv-dev
sudo apt-get install libopencv-dev
---網易雲課堂