1.基本語法
src = cv.imread("E:\\1.jpg")? ? ? ?//獲取圖片位置
cv.namedWindow("Image"疚鲤,cv.WINDOW_AUTOSIZE)? ?//命名顯示窗口并設(shè)置屬性
cv.imshow("Image",img)? ?//顯示窗口并將圖片顯示
cv.waitKey(0)? //等待輸入響應(yīng)
cv.destroyAllWindows()? ?//銷毀窗口
2.圖像加載與保存
圖片屬性? ?
1.通道數(shù)目
2.高寬
3.像素數(shù)據(jù)
4.圖像類型
圖片屬性獲取
print(type(image))? ? ? ? ? //顯示image類型
print(image.shape)? ? ? ? //顯示圖片寬高和通道數(shù)
print(image.size)? ? ? ? ? ? //顯示總像素數(shù)據(jù)大小
print(image.dtype)? ? ? ? ? ? ?//通道所占位數(shù)
攝像頭獲取
capture=cv.VideoCapture(0)? ? ?//獲取視頻
while(True):
ret, frame=capture.read()? ? ? ? ? //調(diào)用攝像頭
frame=cv.flip(frame,1)? ? ? ? ? ? ? ? //鏡像調(diào)整
cv.imshow("video",frame)? ? ? ? ? ?//顯示窗口
c=cv.waitKey(50)
if c==27:
break
保存圖片
cv.imwrite("E:/result.png",img)? ? ? //將img保存在路徑下并命名與格式
3.Numpy數(shù)組操作
包介紹詳細? ?www.numpy.org
作用:
遍歷數(shù)組中的每個像素點
修改數(shù)組中像素點的值
data\dtype\size\shape\len
遍歷圖像像素
def access_pixels(image):
print(image.shape)
height=image.shape[0]
width=image.shape[1]
channel=image.shape[2]
print("width:%s,height:%s,channels:%s"%(width,height,channel))
for rowin range(height):
for colin range(width):
for cin range(channel):
pv = image[row, col, c]
image[row,col,c]=255-pv
cv.imshow("pixels_demo",image)
注:對于上述操作可以用像素取反函數(shù)完成
def inverse(image):
dst=cv.bitwise_not(image)? ?//像素取反
cv.imshow("show",dst)
初始化圖片
np.zeros([400,400,3],np.uint8)? ?//初始化0
np.ones([400,400])*255? ? ? ?//初始化1
fill(122)? ? ? ? ? //填充數(shù)組
reshape([1,9])? ? ? //改變數(shù)組形狀
4.色彩空間
相關(guān)概念
RGB系草,HSV, HIS,YCrCb, YUV
代碼檢測:
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
cv.imshow("gray",gray)
hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
cv.imshow("hsv",hsv)
yuv = cv.cvtColor(image, cv.COLOR_BGR2YUV)
cv.imshow("yuv", yuv)
Ycrcb = cv.cvtColor(image, cv.COLOR_BGR2YCrCb)
cv.imshow("Ycrcb", Ycrcb)
色彩空間轉(zhuǎn)換API
用inRange處理
獲取視頻中的藍色:
capture = cv.VideoCapture("E:\\test.mp4")
while(True):
ret, frame = capture.read()
if ret ==False:
break
? ? hsv=cv.cvtColor(frame, cv.COLOR_BGR2HSV)
lower=np.array([100,43,46])
upper=np.array([124,255,255])#藍色區(qū)域范圍
? ? mask=cv.inRange(hsv,lowerb=lower,upperb=upper)? ??
cv.imshow("mask",mask)
cv.imshow("video", frame)
c = cv.waitKey(40)
if c ==27:
break
分離與合并通道
r,g,b= cv.split(src)? #分離
cv.imshow("blue",b)
cv.imshow("green",g)
cv.imshow("red",r)
cv.merge([r,g,b])? #合并
5.像素運算
算術(shù)運算?
加減乘除——調(diào)節(jié)亮度,對比度
def add_demo(m1,m2):
dst = cv.add(m1, m2)? ? ? ? ? ?#加
cv.imshow("add", dst)
def subtract_demo(m1,m2):
dst = cv.subtract(m1, m2)? ? ? ? ? ? #減
cv.imshow("substract", dst)
def divide_demo(m1,m2):
dst = cv.divide(m1, m2)? ? ? ? ? ?#除
cv.imshow("divide", dst)
def multiply_demo(m1,m2):
dst = cv.multiply(m1, m2)? ? ? ? ? ?#乘
cv.imshow("multiply", dst)
注:mean(src)? ?#求均值
M,dev? =? ?meanStdDev(src)? ? ? ? #返回均值和方差(對比度)
邏輯運算
與或非——遮罩層控制
dst = cv.bitwise_and(m1, m2)? ? ?#與
dst = cv.bitwise_or(m1, m2)? ? ? #或
dst = cv.bitwise_not(m1)? ? ? #非
調(diào)整亮度對比度
#調(diào)整對比度與亮度 c:對比度伴逸,b:亮度
def contract_brightness_demo(image,c,b):
h,w,ch=image.shape
blank=np.zeros([h,w,ch],image.dtype)? ? ? ? ? ? ? ?#調(diào)整亮度對比度
dst=cv.addWeighted(image,c,blank,1-c,b)
cv.imshow("con_bri_demo", dst)
6.ROI與泛洪填充
注:ROI:所選處理區(qū)域
#改變圖片某區(qū)域顏色
face= src[50:250,100:300]
gray=cv.cvtColor(face,cv.COLOR_BGR2GRAY)
backface=cv.cvtColor(gray,cv.COLOR_GRAY2BGR)
face= src[50:250,100:300]=backface?
cv.imshow("face",src)
泛洪填充
def fill_color_demo(image):
copyImg=image.copy()
h,w=image.shape[:2]
mask= np.zeros([h+2,w+2],np.uint8)
cv.floodFill(copyImg,mask,(30,30),(0,255,255),(100,100,100),(50,50,50), cv.FLOODFILL_FIXED_RANGE)? ? ? #改變圖像? ?泛洪填充
cv.imshow("fill_color",copyImg)
def fill_binary():
image=np.zeros([400,400,3],np.uint8)
image[100:300 , 100:300 , :] =255
? ? cv.imshow("fill_binary",image)
mask=np.ones([402,402,1],np.uint8)
mask[101:301,101:301] =0
? ? cv.floodFill(image,mask,(200,200),(0,0,255),cv.FLOODFILL_MASK_ONLY)? ? ? ??
#不改變圖像? ?只填充遮罩層
cv.imshow("filled binary",image)
floodFill()
floodFill(Mat image,Mat mask,Point seedPoint,Scalar newVal)
floodFill(image, mask, seedpoint ,newVal,rect,loDiff,upDiff,flags)
src(seed.x,seed.y)-loDiff<=src(x,y)<=src(seed.x,seed.y)+upDiff合并圖像
作用:合并圖像
7.模糊操作
均值模糊奸绷,中值模糊狡耻,自定義模糊
模糊是卷積的一種表象
dst=cv.blur(image,(15,1))? ? ? ? ? #x方向15像素卷積,y方向1像素卷積咐低,不模糊
dst=cv.medianBlur(image,5)? ? ? ? ?#中值模糊? ?常用于去燥點
kernel=np.ones([5,5],np.float32)/25
dst=cv.filter2D(image,-1,kernel=kernel)? ? ? ? ? ?#自定義模糊
高斯模糊
def clamp(pv):
if pv>255:
return 255
? ? if pv<0:
return 0
? ? else:
return pv
高斯模糊原理代碼
def gaosi_noise(image):
h,w,c = image.shape
for rowin range(h):
for colin range(w):
s=np.random.normal(0,20,3)
b=image[row,col,0]#blue
? ? ? ? ? ? g=image[row,col,1]#green
? ? ? ? ? ? r=image[row,col,2]#red
? ? ? ? ? ? image[row,col,0] = clamp(b+s[0])
image[row,col,1] = clamp(g+s[1])
image[row,col,2] = clamp(r+s[2])
cv.imshow("noise image",image)
API內(nèi)置函數(shù)
dst=cv.GaussianBlur(src,(0,0),15)? ? ? ? ? #0*0高斯模糊? ? ?
8.邊緣保留濾波(EPF)
高斯雙邊,均值遷移袜腥,操作
雙邊模糊:
dst=cv.bilateralFilter(image,0,100,15)? ? ? ? ? ??
均值遷移:
dst=cv.pyrMeanShiftFiltering(image,10,50)
作用:美顏见擦,磨皮美白
9.圖像直方圖(待學(xué))
10.模塊匹配
在整個圖像區(qū)域發(fā)現(xiàn)與給定子圖像匹配的小塊區(qū)域
模板匹配算法
通過三種算法匹配
def template_demo():
tpl=cv.imread("E:\\3.png")? ? ?#要匹配的圖片
target=cv.imread("E:\\2.png")? ? ? ? ? #總的大圖片
cv.imshow("tpl",tpl)
cv.imshow("target",target)
method=[cv.TM_SQDIFF_NORMED,cv.TM_CCORR_NORMED,cv.TM_CCOEFF_NORMED]
th,tw=tpl.shape[:2]
for mdin method:
print(md)
result=cv.matchTemplate(target,tpl,md)
min_val,max_val,min_loc,max_loc=cv.minMaxLoc(result)
if md==cv.TM_SQDIFF_NORMED:
tl=min_loc
else:
tl=max_loc
br =(tl[0]+tw,tl[1]+th)
cv.rectangle(target,tl,br,(0,0,255),2)
cv.imshow("match-"+np.str(md),target)
11.圖像二值化
二值圖像(Binary Image), 二值化方法
二值化方法:
全局閾值瞧挤,局部閾值
全局閾值:
OTSU方法閾值
def threshold_demo(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret, binary=cv.threshold(gray,0,255,cv.THRESH_BINARY | cv.THRESH_OTSU)? ? ?
#0,255表示偏向的兩極
print("threshold value %s"%ret)
cv.imshow("binary",binary)
cv.THRESH_TRIANGLE方法
局部閾值:
def local_threshold_demo(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
binary=cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_MEAN_C,cv.THRESH_BINARY,25,10)
#ADAPTIVE_THRESH_MEAN_C方法
#還有ADAPTIVE_THRESH_GAUSSIAN_C方法
cv.imshow("binary",binary)
自定義:
def custom_threshold_demo(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
h,w=gray.shape[:2]
m=np.reshape(gray,[1,w*h])
mean=m.sum()/(w*h)
print("mean:",mean)
ret,binary=cv.threshold(gray,mean,255,cv.THRESH_BINARY)
cv.imshow("binary",binary)
超大圖片二值化
def image_big_binary(image):
print(image.shape)
cw =256
? ? ch =256
? ? h,w=image.shape[:2]
gray =cv.cvtColor(image,cv.COLOR_BGR2GRAY)
for rowin range(0,h,ch):
for colin range(0,w,cw):
roi = gray[row:row+ch,col:cw+col]
ret,dst = cv.threshold(roi, 0, 255, cv.THRESH_BINARY| cv.THRESH_OTSU)
gray[row:row+ch,col:cw+col] =dst
print(np.std(dst),np.mean(dst))
cv.imshow("gray",gray)
12.圖像金字塔
高斯金字塔 與拉普拉斯金字塔锡宋,圖像金字塔原理
圖像金字塔原理? ? ? ? ?reduce=高斯模糊+降采樣
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? expand=擴大+卷積
PyrDown:降采樣
PyrUp:還原
13.圖像梯度
一階導(dǎo)數(shù)與Sobel算子,二階導(dǎo)數(shù)和拉普拉斯算子
Sobel算子
def soble_demo(image):
grad_x = cv.Sobel(image,cv.CV_32F,1,0)? ? ? ? ?//Sobel算子提取邊緣
grad_y = cv.Scharr(image,cv.CV_32F,0,1)? ? ? ? ? ?//Scharr是Sobel算子加強版
gradx=cv.convertScaleAbs(grad_x)
grady=cv.convertScaleAbs(grad_y)
cv.imshow("grad_x",gradx)
cv.imshow("grad_y",grady)
gradxy = cv.addWeighted(gradx,0.5,grady,0.5,0)
cv.imshow("grad",gradxy)
拉普拉斯算子
def lapilian_demo(image):
#dst = cv.Laplacian(image,cv.CV_32F)? ? ? ?#拉普拉斯算子
#lpls = cv.convertScaleAbs(dst)
? ? kernel= np.array([[1,1,1],[1,-8,1],[1,1,1]])
dst=cv.filter2D(image,cv.CV_32F,kernel=kernel)
lpls=cv.convertScaleAbs(dst)
cv.imshow("lapl",lpls)
邊緣提取
canny算法邊緣檢測算法
高斯模糊特恬,灰度轉(zhuǎn)換执俩,計算梯度,非最大信號抑制癌刽,高低閾值鏈接
def canny_demo(image):
blur=cv.GaussianBlur(image,(3,3),0)
gray=cv.cvtColor(blur,cv.COLOR_BGR2GRAY)
xgrad=cv.Sobel(gray,cv.CV_16SC1,1,0)
ygrad=cv.Sobel(gray,cv.CV_16SC1,0,1)
edge_output=cv.Canny(xgrad,ygrad,50,150)? ? ? ? ? ?
#50為低閾值役首,150為高閾值,高一版是低的三倍或兩倍
cv.imshow("Edge",edge_output)
dst=cv.bitwise_and(image,image,mask=edge_output)
cv.imshow("Color_edge",dst)
14.直線檢測
霍夫直線變換檢測
def line_detection(image):
gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY)
edges=cv.Canny(gray,50,150,apertureSize=3)
lines=cv.HoughLines(edges,1,np.pi/180,200)
for linein lines:
print(type(lines))
rho,theta = line[0]
a=np.cos(theta)
b=np.sin(theta)
x0=a*rho
y0=b*rho
x1=int(x0+1000*(-b))
y1=int(y0+1000*(a))
x2=int(x0-1000*(-b))
y2=int(y0-1000*(a))
cv.line(image,(x1,y1),(x2,y2),(0,0,255),2)
cv.imshow("lines",image)
def line_possible(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
lines = cv.HoughLinesP(edges, 1, np.pi /180, 100,minLineLength=50,maxLineGap=10)
for linein lines:
x1,y1,x2,y2=line[0]
cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)
cv.imshow("lines_possible", image)
15.圓檢測
霍夫圓檢測
首先對圖像進行中值濾波
1.檢測邊緣显拜,發(fā)現(xiàn)可能圓心? ? 2.基于第一步開始計算最佳半徑大小
def circle_demo(image):
dst=cv.pyrMeanShiftFiltering(image,10,100)
gary=cv.cvtColor(dst,cv.COLOR_BGR2GRAY)
circle=cv.HoughCircles(gary,cv.HOUGH_GRADIENT,1,50,param1=50,param2=30,minRadius=0,maxRadius=0)
#調(diào)整50這個參數(shù)根據(jù)具體情況調(diào)整
circle=np.uint16(np.around(circle))
for iin circle[0,:]:
cv.circle(image,(i[0],i[1]),i[2],(0,0,255),2)
cv.circle(image,(i[0],i[1]),2,(0,0,255),2)
cv.imshow("circle",image)
16.輪廓檢測
findContours發(fā)現(xiàn)輪廓
drawContours繪制輪廓
用梯度避免閾值煩惱
def contours_demo(image):
dst=cv.GaussianBlur(image,(3,3),0)
gray=cv.cvtColor(dst,cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary",binary)
cloneImg,contours,heriachy=cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
for i,contourin enumerate(contours):
cv.drawContours(image,contours,i,(0,0,255),2)
#填充輪廓最后的2改成-1
print(i)
cv.imshow("contours",image)
17.對象檢測
弧長面積衡奥,多邊形擬合,幾何矩計算
def measure_object(image):
dst = cv.GaussianBlur(image, (3, 3), 0)
gray = cv.cvtColor(dst, cv.COLOR_BGR2GRAY)
ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
print("threshold value %s"%ret)
cv.imshow("binary",binary)
dstt = cv.cvtColor(binary, cv.COLOR_GRAY2BGR)
outImg,contours,hireachy=cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
for i,contourin enumerate(contours):
#cv.drawContours(image, contours, i, (0, 0, 255), 2)
? ? ? ? area = cv.contourArea(contour)
print("area",area)
x, y, w, h = cv.boundingRect(contour)
mm = cv.moments(contour)
print(type(mm))
cx = mm['m10']/mm['m00']
cy = mm['m01']/mm['m00']#找到重心
? ? ? ? cv.circle(image,(np.int(cx),np.int(cy)),3,(0,255,255),-1)
#cv.rectangle(image, (x, y), (x+w), (x+h), (0, 0, 255), 2)
? ? ? ? approxCurve = cv.approxPolyDP(contour, 10, True)? ? ? ? ? ?#逼近邊數(shù)
if approxCurve.shape[0] ==3:
cv.drawContours(dstt, contours, i, (0, 255, 0), 2)
if approxCurve.shape[0]==4:
cv.drawContours(dstt, contours, i, (0, 0, 255), 2)
if approxCurve.shape[0] >4:
cv.drawContours(dstt, contours, i, (255, 0, 0), 2)
print(approxCurve.shape)
cv.imshow("measure", dstt)