飞道的博客

opencv——图形金字塔、轮廓、模板

322人阅读  评论(0)

1、图像金字塔

定义:把图像按照分辨率大小组合成金字塔的形状,主要用于图像的多层级特征提取。

a、高斯金字塔


   
  1. img=cv2.imread( "AM.png")
  2. cv2.imshow( "img",img)
  3. cv2.waitKey()
  4. cv2.destroyAllWindows()
  5. print(img.shape)
第一种:向下采样方法(金字塔从下往上走)——缩小
步骤:1、将原图像与高斯核模板进行卷积操作(先相乘再加在一起)。
2、将所有的偶数行核列去除掉。

高斯核模板(1/16表示归一化)


   
  1. up=cv2.pyrUp(img)
  2. cv2.imshow( "up",up)
  3. cv2.waitKey()
  4. cv2.destroyAllWindows()
  5. print(up.shape)
第二种:向上采样方法(金字塔从上往下走)——放大
步骤:1、将图像在每个方向扩大为原来的两倍,新增的行和列以0填充。
2、使用先前同样的高斯核模板(乘以4)与放大后的图像卷积,获得近似值。

   
  1. down=cv2.pyrDown(img)
  2. cv2.imshow( "down",down)
  3. cv2.waitKey()
  4. cv2.destroyAllWindows()
  5. print(down.shape)

ps:如果对原图像先上采样再下采样,得到的结果比原图像会差一点,因为进行上采样是采用0进行填充放大的,再进行下采样会损失一些信息。

b、laplacian金字塔


   
  1. down=cv2.pyrDown(img)
  2. down_up=cv2.pyrUp(down)
  3. l_1=img-down_up
  4. cv2.imshow( "l_1",l_1)
  5. cv2.waitKey()
  6. cv2.destroyAllWindows()

2、图像轮廓的检测

cv2.findContours(img,mode,method)

mode(轮廓检索模式): 1、RETR_EXTERNAL——只检索最外边的轮廓

2、RETR_LIST——检索所有的轮廓,并将其保存到一条链表上

3、RETR_CCOMP——检索所有的轮廓,并将其组织为两层,顶层是各部分的外部边界,第二层

是空洞的边界

4、RETR_TREE——检索所有的的轮廓,并重构嵌套轮廓的整个层次(最常用的模式)

method(轮廓逼近方法):1、CHAIN_APPROX_NONE——以FREEMAN链码的方式输出轮廓,所有

其他方法输出多边形(顶点的序列)

2、CHAIN_APPROX_SIMPLE——压缩水平的、垂直的和斜的的部分,函数

只保留它们的终点部分

ps:轮廓检测最好是二值化图像


   
  1. img=cv2.imread( "contour.png")
  2. #转化为灰度图像
  3. gray=cv2.cvtColor(img,cv2.BGR2GRAY)
  4. #采用阈值处理转化为二值化图像
  5. ret,thresh=cv2.Threshold(img, 127, 255,cv2.THRESH_BINARY)
  6. cv2.imshow( "thresh",thresh)
  7. cv2.waitKey()
  8. cv2.destroyAllWindows()
  9. #轮廓检测(binary:二值化图像,contours:轮廓点信息,hierarchy:轮廓层级
  10. binary,contours,hierarchy=cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
  11. #绘制轮廓
  12. draw_img=img.copy
  13. #-1是指绘制全部轮廓,其他数字按照从左下开始检测部分轮廓,2是指绘制的线条宽度
  14. res=cv2.drawContours(draw_img,contours,- 1,( 0, 0, 255), 2)
  15. cv2.imshow( "res",res)
  16. cv2.waitKey()
  17. cv2.destroyAllWindows()

3、轮廓计算

a 、轮廓特征(面积和周长)


   
  1. cnt=contours[ 0] #第0个轮廓
  2. cv2.contourArea(cnt) #计算轮廓面积
  3. cv2.arcLength(cnt, True) #计算轮廓周长,True表示闭合

b、轮廓近似

以直代曲:设定一个阈值,如果两点间的曲线弯曲程度大于阈值则用直线代替,否则在中间再找一点,寻找两条直线代替。(类似于二分法)


   
  1. epsilon= 0.1*cv2.arcLength(cnt, True)
  2. approx=cv2.approxPolyDP(cnt,epsilon, True) #近似函数,利用0.1倍周长作为阈值
  3. draw_img=img.copy()
  4. res=cv2.drawContours(draw_img,[approx],- 1,( 0, 0, 255), 2)
  5. cv2.imshow( "res",res)
  6. cv2.waitKey()
  7. cv2.destroyAllWindows()

c、外接图形(边界矩形和外接圆)


   
  1. #边界矩形
  2. x,y,w,h=cv2.boundingRect(cnt)
  3. img=cv2.rectangle(img,(x,y),(x+w,y+h),( 0, 255, 0), 2)
  4. cv2.imshow( "img",img)
  5. cv2.waitKey()
  6. cv2.destroyAllWindows()
  7. #轮廓面积与边界矩形比
  8. area=cv2.contourArea(cnt)
  9. x,y,w,h=cv2.boundingRect(cnt)
  10. rect_area=w*h
  11. extent= float(area)/rect_area
  12. pri( "轮廓面积与边界矩形比:",extent)

   
  1. #外接圆
  2. (x,y),radius=cv2.minEnclosingCircle(cnt)
  3. center=( int(x), int(y))
  4. radius= int(radius)
  5. img=cv2.circle(img,center,radius,,( 0, 255, 0), 2)
  6. cv2.imshow( "img",img)
  7. cv2.waitKey()
  8. cv2.destroyAllWindows()

4、模板匹配

定义:模板匹配类似于卷积,模板在原图像上从原点开始滑动,计算模板与图形被模板覆盖区域的差别程度,将每次计算的结果都保存到一个矩阵里,作为结果输出

假设:模板:a*b 原图像:A*B 输出结果矩阵:(A-a+1)*(B-b+1)

差别程度计算方法:TM_SQDIFF:计算平方不同,值越小,越相关

TM_CCORR:计算相关性,值越大,越相关

TM_CCOEFF:计算相关系数,值越大,越相关

TM_SQDIFF_NORMED:计算归一化平方不同,越接近于0越相关

TM_CCORR_NORMED:计算归一化相关性,越接近于1越相关

TM_CCOEFF_NORMED:计算归一化相关系数,越接近于1越相关

a、匹配单个对象


   
  1. import cv2
  2. import matplotlib.pyplot as plt
  3. img=cv2.imread( "lena.jpg", 0)
  4. template=cv2.imread( "face.jpg", 0)
  5. h,w=template.shape[: 2]
  6. img.shape
  7. template.shape
  8. methods=[ "cv2.TM_CCOEFF", "cv2.TM_CCOEFF_NORMED", "cv2.TM_CCORR", "cv2.TM_CCORR_NORMED", "cv2.TM_SQDIFF", "cv2.TM_SQDIFF_NORMED"]
  9. for meth in methods:
  10. img2=img.copy()
  11. method= eval(meth) #不能是字符串
  12. print(method)
  13. res=cv2.matchTemplate(img2,template,method)
  14. res.shape
  15. min_val,max_val,min_roc,max_roc=cv2.minMaxLoc(res) #最小值,最大值,最小值坐标位置,最大值坐标位置
  16. if method in [cv2.TM_SQDIFF,cv2.TM_SQDIFF_NORMED]:
  17. top_left=min_roc
  18. else :
  19. top_left=max_roc
  20. bottom_right=(top_left[ 0]+w,top_left[ 1]+h)
  21. cv2.rectangle(img2,top_left,bottom_right, 255, 2)
  22. plt,subplot( 121)
  23. plt.imshow(res,cmap= "gray")
  24. plt.xtick([]) #隐藏坐标轴
  25. plt.ytick([])
  26. plt.subtitle(meth)
  27. plt.show()

b、匹配多个模板对象


   
  1. threshold= 0.8 #设定一个阈值
  2. loc=np.where(res>=threshold)
  3. for pt in zip(*loc[::- 1]):
  4. bottom_right=(pt+w,pt+h)
  5. cv2.rectangle(img2,pt,bottom_rigth,( 0, 0, 255), 2)
  6. cv2.imshow( "img2",img2)
  7. cv2.waitKey()
  8. cv2.destroyAllWindows()

转载:https://blog.csdn.net/qq_60445109/article/details/128840354
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场