1.图像基础操作
#1.视频读取,变成灰度视频,调节视频速度: import cv2 as cv video=cv.VideoCapture('lz.mp4') #检查是否打开正确 if video.isOpened: open,frame=video.read()#读取第一帧 else: open=False while open:#当视频可以正确打开时: open_2,frame=video.read()#读取照片 if frame is None:#当图片读完时: break if open_2==True:#当图片没读完,且可以打开时: gray=cv.cvtColor(frame,cv.COLOR_BGR2GRAY)#把图片变成灰度图 cv.imshow('result',gray)#展示图片 if cv.waitKey(3)&0xFF==27:#视频在多少秒内结束,或者按esc键时,推出视频 break video.release() cv.destroyAllWindows() #2. import cv2 as cv img=cv.imread('kst.jpg',1) #2.1颜色通道提取: b,g,r=cv.split(img) #print(b) #2.2颜色通道合并 img=cv.merge((b,g,r)) #print(img.shape) #2.3保留单通道 cur_img=img.copy() cur_img[:,:,0]=0#蓝色全为0 cur_img[:,:,1]=0#绿色通道全为0 cv.imshow('r',cur_img)#红色通道像素值保留 cv.waitKey(0) #3.边界填充 top_size,bottom_size,left_size,right_size=(60,60,60,60)#边界要补多少 replicate=cv.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_REPLICATE) reflect=cv.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_REFLECT) reflect101=cv.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_REFLECT_101) wrap=cv.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_WRAP) constant=cv.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv.BORDER_CONSTANT,value=0) cv.imshow('a',constant) cv.waitKey(0) #4.图像用add img_1=img+100#+,溢出255时,取余数 #print(img_1) cv.imshow('1',img_1) img_2=cv.add(img,100)#add,溢出255时,取255 #print(img_2) cv.imshow('2',img_2) cv.waitKey(0) #5.阈值操作 ret,dst1=cv.threshold(img,127,255,cv.THRESH_BINARY)#1原图,2阈值,3最大值,4类型 ret,dst2=cv.threshold(img,127,255,cv.THRESH_BINARY_INV) ret,dst3=cv.threshold(img,127,255,cv.THRESH_TRUNC) ret,dst4=cv.threshold(img,127,255,cv.THRESH_TOZERO) ret,dst5=cv.threshold(img,127,255,cv.THRESH_TOZERO_INV) cv.imshow('DST',dst5) cv.waitKey(0) import matplotlib.pyplot as plt titles=['original image','binary','binary inv','trunc','tozero','tozero inv'] images=[img,dst1,dst2,dst3,dst4,dst5] for i in range(6): plt.subplot(2,3,i+1),plt.imshow(images[i],'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() #6.滤波: #1.均值滤波 blur=cv.blur(img,(3,3)) #2.方框滤波 box=cv.boxFilter(img,-1,(3,3),normalize=False)#false容易越界,true和均值滤波一样 #3.高斯滤波 gaussian=cv.GaussianBlur(img,(5,5),1) #4.中值滤波 median=cv.medianBlur(img,5) #显示所有图片 import numpy as np res=np.vstack((blur,gaussian,median)) #print(res) cv.imshow('DST',res) cv.waitKey(0) import cv2 as cv #7.形态学操作 #7.1腐蚀操作 #kernel=np.ones((5,5),np.uint8) kernel=cv.getStructuringElement(cv.MORPH_RECT,(5,5))#kernel形状 erosion=cv.erode(img,kernel,iterations=1)#iterations腐蚀次数 #7.2膨胀操作 kernel=np.ones((3,3),np.uint8) dilate=cv.dilate(img,kernel,iterations=1) #7.3开运算:先腐蚀再膨胀 kernel=np.ones((5,5),np.uint8) opening=cv.morphologyEx(img,cv.MORPH_OPEN,kernel) #7.4闭运算:先膨胀再腐蚀 closing=cv.morphologyEx(img,cv.MORPH_CLOSE,kernel) #7.5梯度运算:膨胀图片-腐蚀图片=边界信息 gradient=cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel) #7.6礼帽:原始输入-开运算结果=毛刺 tophat=cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel) #7.7黑帽:闭运算-原始输入==原始轮廓 blackhat=cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel) #7.8图像梯度 dst=cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel) cv.imshow('DST',blackhat) cv.waitKey(0) #8.图像梯度 #8.1sobel算子 sobelx=cv.Sobel(img,cv.CV_64F,1,0,ksize=3)#1img,2图像深度(-1)(CV_64F保留负值,不让赋值=0),3dx(1算,0不算),4dy,5sobel算子的大小 sobelx=cv.convertScaleAbs(sobelx)#将上一步的计算的负值取绝对值,得到边缘信息 sobely=cv.Sobel(img,cv.CV_64F,0,1,ksize=3) sobely=cv.convertScaleAbs(sobely) #反别计算x和y,再求和 sobelxy=cv.addWeighted(sobelx,0.5,sobely,0.5,0)#0是偏置项,一般不加偏置项 #8.2scharr算子 scharrx=cv.Scharr(img,cv.CV_64F,1,0)#ksize默认3 scharrx=cv.convertScaleAbs(scharrx) scharry=cv.Scharr(img,cv.CV_64F,0,1) scharry=cv.convertScaleAbs(scharry) scharrxy=cv.addWeighted(scharrx,0.5,scharry,0.5,0) #8.3laplacian算子 laplacian=cv.Laplacian(img,cv.CV_64F) laplacian=cv.convertScaleAbs(laplacian) res=np.hstack((sobelxy,scharrxy,laplacian)) cv.imshow('DST',res) cv.waitKey(0) #9.canny边缘检测(含有零零散散的线段):高斯滤波,计算像素的梯度强度和方向,非极大值抑制,双阈值, gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) canny=cv.Canny(gray,80,150)#1灰度图片,2双阈值检测minvalue,3maxvalue cv.imshow('DST',canny) cv.waitKey(0) #10.图像金字塔 #10.1高斯金字塔上采样:kernel print(img.shape) up=cv.pyrUp(img) print(up.shape) #金字塔下采样 down=cv.pyrDown(img) print(down.shape) #10.2拉普拉斯金字塔:原图-(上采样(下采样)) down=cv.pyrDown(img) down_up=cv.pyrUp(down) laplaus=img-down_up cv.imshow('dst',laplaus) cv.waitKey(0) img=cv.imread('figure.jpg',1) gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) #11.轮廓检测(不含零散的线段): #mode:RETR_EXTERNAL只检测最外面轮廓,RETR_LIST检测所有轮廓,RETR_CCOMP分两层,RETR_TREE嵌套(最常用) #method:CHAIN_APPROX_NONE,CHAIN_APPROX_SIMPLE #-1二值图像,轮廓信息 ret,thresh=cv.threshold(gray,0,255,cv.THRESH_BINARY)#图像二值 contours,hierarchy=cv.findContours(thresh,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_NONE) #contours轮廓信息,hierarchy层级信息 #-2绘制轮廓 draw_img=img.copy()#复制原图像 res=cv.drawContours(draw_img,contours,-1,(0,0,255),-1)#1在哪个图片上画,2画的轮廓信息,3画几条轮廓,4画笔颜色,5画笔粗细 #-3分析轮廓特征 cnt=contours[0]#拿出第0条轮廓信息 res=cv.drawContours(draw_img,cnt,-1,(0,255,0),2) area=cv.contourArea(cnt)#计算第0条轮廓的面积 perimeter=cv.arcLength(cnt,True)#计算周长,True表示闭合 #-4轮廓近似 epsilon=0.1*cv.arcLength(cnt,True)#周长的0.1倍作为轮廓近似的阈值 approx=cv.approxPolyDP(cnt,epsilon,True) draw=img.copy() res=cv.drawContours(draw,[approx],-1,(255,0,0),2) print(area,perimeter) #-5.轮廓的外接矩形 x,y,w,h=cv.boundingRect(cnt)#第0条轮廓的外接矩形参数 res=cv.rectangle(img,(x,y),(x+w,y+h),(255,0,0),3)#画 #-6.轮廓外接圆 (x,y),radius=cv.minEnclosingCircle(cnt) center=(int(x),int(y)) radius=int(radius) res=cv.circle(img,center,radius,(0,0,255),3) cv.imshow('dst',res) cv.waitKey(0) #12.模板匹配 import matplotlib.pyplot as plt img=cv.imread('kst.jpg',0) head=cv.imread('head.jpg',0) h=head.shape[0] w=head.shape[1] print(img.shape,head.shape) #TM_SQDIFF:计算平方不同,计算出来的值越小,越相关 #TM_CCORR:计算相关性,值越大,越相关 #TM_CCOEFF:计算相关系数,值越大,越相关 #TM_SQDIFF_NORMED:计算归一化平方不同,值越接近0,越相关 #TM_CCORR_NORMED:计算归一化,越接近1,越相关 #TM_CCOEFF_NORMED:计算归一化相关系数,越接近1,越相关 res=cv.matchTemplate(img,head,cv.TM_SQDIFF)#匹配返回的是每次计算完的结果 print(res.shape)#(A-a+1)*(B-b+1) min_val,max_val,min_loc,max_loc=cv.minMaxLoc(res)#找出这个矩阵里最值和位置 methods=['cv.TM_SQDIFF','cv.TM_CCORR','cv.TM_CCOEFF','cv.TM_SQDIFF_NORMED','cv.TM_CCORR_NORMED','cv.TM_CCOEFF_NORMED'] for meth in methods: img2=img.copy() method=eval(meth)#字符串形式化成专有名词 res=cv.matchTemplate(img,head,method) min_val,max_val,min_loc,max_loc=cv.minMaxLoc(res) if method in [cv.TM_SQDIFF,cv.TM_SQDIFF_NORMED]: top_left=min_loc else: top_left=max_loc bottom_right=(top_left[0]+w,top_left[1]+h) #画矩形 cv.rectangle(img2,top_left,bottom_right,255,2) plt.subplot(121),plt.imshow(res,cmap='gray') plt.xticks([]),plt.yticks([])#隐藏坐标img plt.subplot(122),plt.imshow(img2,cmap='gray') plt.xticks([]),plt.yticks([])#隐藏坐标 plt.suptitle(meth) plt.show() #12.2匹配多个对象 import cv2 as cv import numpy as np img=cv.imread('AA.jpg',1) imh=cv.imread('AA.jpg',0) head=cv.imread('BB.jpg',0) h,w=head.shape[:2] res=cv.matchTemplate(imh,head,cv.TM_CCOEFF_NORMED)#匹配计算 threshold=0.7#阈值 loc=np.where(res>=threshold)#大于阈值的挑出来 for pt in zip(*loc[::-1]):#*号表示可选参数: bottom_right=(pt[0]+w,pt[1]+h) cv.rectangle(img,pt,bottom_right,(0,0,225),3) cv.imshow('img',img) cv.waitKey(0) import cv2 as cv import numpy as np img=cv.imread(r'D:\paper\vgg_segnet\dataset2\jpg\C_0001_1.RIGHT_MLO.jpg',0) img=cv.resize(img,(260,250)) #.createCLAHE函数原型:createCLAHE([, clipLimit[, tileGridSize]]) -> retval #clipLimit参数表示对比度的大小。 #tileGridSize参数表示每次处理块的大小 equ=cv.equalizeHist(img) clahe=cv.createCLAHE(clipLimit=9.0,tileGridSize=(3,3)) res_clahe=clahe.apply(img) res=np.hstack((equ,img,res_clahe)) cv.imshow('aaa',res) cv.waitKey(0) #plt.show() #13.直方图 import cv2 as cv import matplotlib.pyplot as plt import numpy as np #灰度直方图 gray=cv.imread('kst.jpg',0)#读取灰度图 hist=cv.calcHist([gray],[0],None,[256],[0,256]) #1【图像】,2第几通道【0,1,2】,3掩膜(自己选的范围内),4bin数,分成几段,5从0到255 #彩色直方图 img=cv.imread('kst.jpg') color=['b','g','r'] for i,col in enumerate(color):#i是坐标,col是内容 histr=cv.calcHist([img],[i],None,[256],[0,256]) #plt.plot(histr,color=col) #plt.xlim([0,256]) #plt.hist(gray.ravel(),256) #直方图均衡化 equ=cv.equalizeHist(gray) #plt.hist(equ.ravel(),256) #自适应直方图均衡化 clahe=cv.createCLAHE(clipLimit=2.0,tileGridSize=(8,8)) res_clahe=clahe.apply(gray) res=np.hstack((gray,equ,res_clahe)) cv.imshow('res',res) cv.waitKey(0) #plt.show() #14.傅里叶变换,输入图像要先转换成np.float32格式,dft,idft import numpy as np import cv2 as cv import matplotlib.pyplot as plt gray=cv.imread('kst.jpg',0) gray_float32=np.float32(gray)#灰度图像先转换成float32位的 dft=cv.dft(gray_float32,flags=cv.DFT_COMPLEX_OUTPUT)#傅里叶变换 dft_shift=np.fft.fftshift(dft)#将低频信息转换到中间位置 magnitude_spectrum=20*np.log(cv.magnitude(dft_shift[:,:,0],dft_shift[:,:,1])) #利用公式转换成可以以图片格式显示 plt.subplot(121),plt.imshow(gray,cmap='gray') plt.title('input image'),plt.xticks([]),plt.yticks([]) plt.subplot(122),plt.imshow(magnitude_spectrum,cmap='gray') plt.title('magnitude_spectrum'),plt.xticks([]),plt.yticks([]) plt.show() #14-2低通滤波 #14-3高通滤波 #14-2低通滤波 import numpy as np import cv2 as cv import matplotlib.pyplot as plt img=cv.imread('kst.jpg',1) gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) gray_float=np.float32(gray) dft=cv.dft(gray_float,flags=cv.DFT_COMPLEX_OUTPUT) dft_shift=np.fft.fftshift(dft) rows,cols=gray.shape#总高,宽 crow,ccol=int(rows/2),int(cols/2)#中心位置 #低通滤波 mask=np.zeros((rows,cols,2),np.uint8)#黑色 mask[crow-30:crow+30,ccol-30:ccol+30]=1#白色 #IDFT fshift=dft_shift*mask f_ishift=np.fft.ifftshift(fshift) img_back=cv.idft(f_ishift) img_back=cv.magnitude(img_back[:,:,0],img_back[:,:,1]) #plot plt.subplot(121),plt.imshow(gray,cmap='gray') plt.title('input image'),plt.xticks([]),plt.yticks([]) plt.subplot(122),plt.imshow(img_back,cmap='gray') plt.title('result image'),plt.xticks([]),plt.yticks([]) plt.show() #14-3高通滤波 import numpy as np import cv2 as cv import matplotlib.pyplot as plt img=cv.imread('kst.jpg',1) gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) gray_float=np.float32(gray) dft=cv.dft(gray_float,flags=cv.DFT_COMPLEX_OUTPUT) dft_shift=np.fft.fftshift(dft) rows,cols=gray.shape#总高,宽 crow,ccol=int(rows/2),int(cols/2)#中心位置 #低通滤波 mask=np.ones((rows,cols,2),np.uint8)# mask[crow-30:crow+30,ccol-30:ccol+30]=0# #IDFT fshift=dft_shift*mask f_ishift=np.fft.ifftshift(fshift) img_back=cv.idft(f_ishift) img_back=cv.magnitude(img_back[:,:,0],img_back[:,:,1]) #plot plt.subplot(121),plt.imshow(gray,cmap='gray') plt.title('input image'),plt.xticks([]),plt.yticks([]) plt.subplot(122),plt.imshow(img_back,cmap='gray') plt.title('result image'),plt.xticks([]),plt.yticks([]) plt.show()
#1.harris import cv2 as cv import numpy as np img=cv.imread('kst.jpg') gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) dst=cv.cornerHarris(gray,2,3,0.04)#1data,2角点检测中指定区域大小,3sobel求导使用的窗口大小,4k参数取值【0.04,0.06 img[dst>0.01*dst.max()]=[0,0,255] cv.imshow('dst',img) cv.waitKey(0) #2.sift import cv2 as cv import numpy as np img=cv.imread('kst.jpg') gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) sift=cv.xfeatures2d.SIFT_create()#实例化 kp=sift.detect(gray,None)#得到特征点 img=cv.drawKeypoints(gray,kp,img) cv.imshow('dst',img) cv.waitKey(0) #计算特征个数,属性 kp,des=sift.compute(gray,kp) print(np.array(kp).shape)#特征点个数 print(des.shape)#关键点特征值
2.