1、边缘保留滤波(EPF)

def bi_demo(image):# bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None) """ sigmaColor大一点,sigmaSpace小一点 同时考虑空间与信息和灰度相似性,达到保边去噪的目的 双边滤波的核函数是空间域核与像素范围域核的综合结果: 在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊; 在图像的边缘区域,像素值变化很大,像素范围域权重变大,从而保持了边缘的信息。 """ dst=cv.bilateralFilter(image,0,100,15) cv.imshow("b1_demo",dst) def shift_demo(image):#均值迁移 dst=cv.pyrMeanShiftFiltering(image,10,50) cv.imshow("shift_image",dst)
2、图像直方图




def plot_demo(image): plt.hist(image.ravel(),256,[0,256]) plt.show() def image_hist(image): color=('blue','green','red')#画出三条线 绘制每个颜色对应的直方图 for i,color in enumerate(color): hist=cv.calcHist(image,[i],None,[256],[0,256]) plt.plot(hist,color=color) plt.xlim([0,256]) plt.show() def equalHist_demo(image): gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) #全局直方图均衡化,用于增强图像对比度,黑的更黑,白的更白 dst=cv.equalizeHist(gray) cv.imshow("equalHist_demo",dst) def clahe_demo(image):#局部直方图均衡化 gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) #提供多一种选择,更好 clahe=cv.createCLAHE(clipLimit=2.0,tileGridSize=(8,8)) dst=clahe.apply(gray) cv.imshow("clahe_demo",dst) def create_rgb_demo(image): h,w,c=image.shape rgbHist=np.zeros([16*16*16,1],np.float32) bsize=256/16 for row in range(h): for col in range(w): b=image[row,col,0] g=image[row,col,1] r=image[row,col,2] index=np.int(b/bsize)*16*16+np.int(g/bsize)*16+np.int(r/bsize) rgbHist[np.int(index),0]=rgbHist[np.int(index),0]+1 return rgbHist def hist_compare(image1,image2): hist1=create_rgb_demo(image1) hist2=create_rgb_demo(image2) match1=cv.compareHist(hist1,hist2,method=cv.HISTCMP_BHATTACHARYYA) match2=cv.compareHist(hist1,hist2,method=cv.HISTCMP_CORREL) match3=cv.compareHist(hist1,hist2,method=cv.HISTCMP_CHISQR) print("巴氏距离:%s,相关性:%s,卡方:%s"%(match1,match2,match3)) #巴氏距离越大,越不相关, 相关性越大越想像, 卡方越小越相关, src1=cv.imread("D:/opencvimage/01.jpg") src2=cv.imread("D:/opencvimage/02.jpg") src = cv.imread("D:/opencvimage/rice.png") image1= cv.imread("D:/opencvimage/rice.png") image2= cv.imread("D:/opencvimage/rice.png") cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) cv.imshow("input image",src) image_hist(src) equalHist_demo(src) clahe_demo(src) hist_compare(src1,src2)

3、直方图反向投射

def back_projection_demo(): sample=cv.imread("D:/opencvimage/sample.PNG") target=cv.imread("D:/opencvimage/messi5.jpg") roi_hsv=cv.cvtColor(sample,cv.COLOR_BGR2HSV) target_hsv=cv.cvtColor(target,cv.COLOR_BGR2HSV) #show image cv.imshow("sample",sample) cv.imshow("target",target) roiHist=cv.calcHist([roi_hsv],[0,1],None,[4,4],[0,180,0,256]) #之前选择的是 beans=【180,256】产生的越多越细分越厉害 产生的结果碎片化 cv.normalize(roiHist,roiHist,0,255,cv.NORM_MINMAX) dst=cv.calcBackProject([target_hsv],[0,1],roiHist,[0,180,0,256],1) # dst1=cv.bitwise_or(dst,target_hsv)相与 cv.imshow("backprojectiondemo",dst) def hist2d_demo(image): hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV) hist=cv.calcHist([image],[0,1],None,[32,32],[0,180,0,256]) plt.imshow(hist,interpolation="nearest") plt.title("2D HIstgram") plt.show() src1=cv.imread("D:/opencvimage/01.jpg") src2=cv.imread("D:/opencvimage/02.jpg") src = cv.imread("D:/opencvimage/lena.jpg") back_projection_demo() hist2d_demo(src) cv.waitKey(0) cv.destroyWindow()
4、模板匹配
三种不同方法找到匹配到姚明
def template_demo(): tpl=cv.imread("D:/opencvimage/yaoming.png") targrt=cv.imread("D:/opencvimage/quanmingxing.jpg") cv.imshow("template",tpl) cv.imshow("target",targrt) methods = [cv.TM_SQDIFF_NORMED, cv.TM_CCORR_NORMED, cv.TM_CCOEFF_NORMED] # 三种模板匹配方法 th,tw=tpl.shape[:2] for md in methods: print(md) result=cv.matchTemplate(targrt,tpl,md) min_val,max_val,min_loc,max_loc=cv.minMaxLoc(result) if md==cv.TM_SQDIFF_NORMED:# cv.TM_SQDIFF_NORMED最小时最相似,其他最大时最相似 tl=min_loc#tl为矩阵的左上角那个点 else: tl=max_loc br=(tl[0]+tw,tl[1]+th)#bottom right 加上模板的宽和高 cv.rectangle(targrt,tl,br,(0,0,255),2) cv.imshow("match_"+np.str(md),targrt) src1=cv.imread("D:/opencvimage/01.jpg") src2=cv.imread("D:/opencvimage/02.jpg") src = cv.imread("D:/opencvimage/lena.jpg") template_demo() cv.waitKey(0) cv.destroyAllWindows()
也可以看看result,看看不同方法显示的结果

5、图像二值化

全局与局部二值化
# 二值图像就是将灰度图转化成黑白图,没有灰,在一个值之前为黑,之后为白 # 有全局和局部两种 # 在使用全局阈值时,我们就是随便给了一个数来做阈值,那我们怎么知道我们选取的这个数的好坏呢?答案就是不停的尝试。 # 如果是一副双峰图像(简 单来说双峰图像是指图像直方图中存在两个峰)呢? # 我们岂不是应该在两个峰之间的峰谷选一个值作为阈值?这就是 Otsu 二值化要做的。 # 简单来说就是对 一副双峰图像自动根据其直方图计算出一个阈值。 # (对于非双峰图像,这种方法 得到的结果可能会不理想)。 def threshold_demo(image): gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) # 这个函数的第一个参数就是原图像,原图像应该是灰度图。 # 第二个参数就是用来对像素值进行分类的阈值。 # 第三个参数就是当像素值高于(有时是小于)阈值时应该被赋予的新的像素值 # 第四个参数来决定阈值方法,见threshold_simple() # ret, binary = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) # ret,binary=cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU) ret,binary=cv.threshold(gray,122,255,cv.THRESH_BINARY)#INV反过来 # cv.THRESH_TRUNC截断效果 大于阈值就等于给定的值 print("threshold value:%s"%ret) cv.imshow("binary",binary) def local_threshold(image):#局部二值化 #局部 会更好的表现特征 gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) binary=cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,25,10) # print("threshold value:%s" % ret) cv.imshow("binary", binary) def custom_threshold(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:%s"%mean) ret,binary=cv.threshold(gray,mean,255,cv.THRESH_BINARY) #ret是阈值=mean # binary=cv.adaptiveThreshold(gray,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,25,10) # print("threshold value:%s" % ret) cv.imshow("binary", binary) src1=cv.imread("D:/opencvimage/01.jpg") src2=cv.imread("D:/opencvimage/02.jpg") src = cv.imread("D:/opencvimage/lena.jpg") threshold_demo(src) # custom_threshold(src) cv.waitKey(0) cv.destroyWindow()
6、局部二值化的方法,超大图像二值化



def big_image_binary(image):#分割成小块进行全局二值化 print(image.shape) cw=256 ch=256 h,w=image.shape[:2] gray=cv.cvtColor(image,cv.COLOR_BGR2GRAY) for row in range(0,h,ch): for col in 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) # 分割成小块进行全局二值化 # dst=cv.adaptiveThreshold(roi,255,cv.ADAPTIVE_THRESH_GAUSSIAN_C,cv.THRESH_BINARY,127,20) # 分割成小块进行局部二值化,大于127超过20才会变255 #再或者,设置一个阈值,roi<某个值,就使变为255 print(np.std(roi),np.mean(roi)) dev=np.std(roi) if dev<10: gray[row:row + ch, col:cw + col]=255 else: ret,dst=cv.threshold(roi,0,255,cv.THRESH_OTSU|cv.THRESH_BINARY) gray[row:row + ch, col:cw + col]=dst cv.imwrite("D:/opencvimage/result_binary.png",gray) src1=cv.imread("D:/opencvimage/01.jpg") src2=cv.imread("D:/opencvimage/02.jpg") src = cv.imread("D:/opencvimage/big_image.jpg") big_image_binary(src) cv.waitKey(0) cv.destroyAllWindows()
7、图像金字塔


# 图像金字塔和拉普拉斯金字塔(L1 = g1 - expand(g2)):reduce:高斯模糊+降采样,expand:扩大+卷积 # PyrDown降采样,PyrUp还原 def pyramid_demo(image):#reduce金字塔 level=3 temp=image.copy() pyramid_images=[] for i in range(level): dst=cv.pyrDown(temp) pyramid_images.append(dst) cv.imshow("pyramid_down_"+str(i),dst) temp=dst.copy() return pyramid_images def lapalian_demo(image): pyramid_images=pyramid_demo(image) level=len(pyramid_images) for i in range(level-1,-1,-1): if (i-1)<0: expand = cv.pyrUp(pyramid_images[i], dstsize=image.shape[:2]) lpls = cv.subtract(image, expand) cv.imshow("lapalian_down" + str(i), lpls) else: expand = cv.pyrUp(pyramid_images[i], dstsize=pyramid_images[i - 1].shape[:2]) lpls = cv.subtract(pyramid_images[i - 1], expand) cv.imshow("lapalian_down" + str(i), lpls)
浙公网安备 33010602011771号