4.9 轮廓检测

轮廓发现与绘制

cv2.findContours()
cv2.drawContours()

轮廓是沿边界的具有相似颜色或强度的所有连续点组成的曲线。

  • 为了更好的精度,使用二值图像。在轮廓发现前,使用阈值法或者Canny边缘检测。
  • 轮廓发现是在黑色背景中找出白色物体。
%matplotlib inline               
import cv2               
import numpy as np               
import matplotlib.pyplot as plt               


# Create test image               
img = np.zeros((400, 400, 3), dtype=np.uint8)               
img[49:350, 49:350] = 255               
img[99:200, 99:200] = 0               
img[249:300, 249:300] = 0               
img[269:280, 269:280] = 255               

# 绘制图像               
plt.imshow(img, cmap='gray')               

# 保存图像               
cv2.imwrite('../data/test.jpg', img)               

测试用的图片

# 读取图像      
im = cv2.imread('../data/test.jpg')
      
# 判断图像是否为空      
assert im is not None, "file could not be read, check with os.path.exists()"

# 将图像转化为灰度图    
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)      

# 图像二值化       
ret, thresh = cv2.threshold(imgray, 127, 255, 0)  

# 轮廓发现
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 所有轮廓绘制
cv2.drawContours(im, contours, -1, (0, 255, 0), 3)
plt.imshow(im)

所有轮廓绘制结果

# 指定轮廓绘制
cnt = contours[3] 
cv2.drawContours(im, [cnt], 0, (0, 0 , 255), 3) 

# 显示图像 
plt.imshow(im) 

指定轮廓绘制结果

轮廓逼近法的不同

传递cv2.CHAIN_APPROX_NONE,则存储所有边界点。cv2.CHAIN_APPROX_SIMPLE会删除了所有冗余点并压缩了轮廓,从而节省了内存。
通过cv2.findContours()得到的contours是Tuple类型。在本实例中,len(contours)的值为4,代表检测到了4个轮廓,每个轮廓包含点的维度是(n, 1, 2),n代表点的个数,2表示点的二维坐标。

# 发现轮廓,并使用cv2.CHAIN_APPROX_NONE模式                      
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

# 绘制组成轮廓的所有边界点 
for i, cnt in enumerate(contours):     
    for point in cnt[:, 0, :]: 
    	# 不同轮廓上绘制的边界点颜色不一样  
        if i == 0:     
            cv2.circle(img, point, 1, (255, 0, 0), 2)     
        elif i == 1:     
            cv2.circle(img, point, 1, (255, 255, 0), 2)     
        elif i == 2:     
            cv2.circle(img, point, 1, (0, 0, 255), 2)    
        else:    
            cv2.circle(img, point, 1, (0, 255, 0), 2)   

# 显示图像 
plt.imshow(img)  

CHAIN_APPROX_NONE实例

# 发现轮廓,并使用cv2.CHAIN_APPROX_SIMPLE模式                                            
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 绘制组成轮廓的所有边界点                
for i, cnt in enumerate(contours):                    
    for point in cnt[:, 0, :]:                
    	# 不同轮廓上绘制的边界点颜色不一样                 
        if i == 0:                    
            cv2.circle(img, point, 1, (255, 0, 0), 2)                    
        elif i == 1:                    
            cv2.circle(img, point, 1, (255, 255, 0), 2)                    
        elif i == 2:                    
            cv2.circle(img, point, 1, (0, 0, 255), 2)                   
        else:                   
            cv2.circle(img, point, 1, (0, 255, 0), 2)                  

# 显示图像                
plt.imshow(img)                 

CHAIN_APPROX_SIMPLE实例

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值