7. OpenCV - 画像の輪郭

1. OpenCV の findContours を使用すると、画像内のコンテンツの輪郭を簡単に見つけることができます。

2. 輪郭抽出の精度を高めるために、輪郭を抽出する前に画像を前処理 (バイナリ値 + 閾値) し、目的の画像のみを保持する必要があります。

3. 輪郭面積と外接長方形または外接円の面積を計算することで、輪郭の特徴を求め、さらに注目する輪郭を選別することができます。

CHAIN_APPROX_SIMPLE: 水平、垂直、斜めの部分を圧縮します。つまり、関数はその端の部分のみを保持します。より高い精度を得るには、バイナリ イメージを使用してください








サンプルコード 

import cv2
import math
import numpy as np

#图像轮廓
#语法:cv2.findContours(img,mode,method)
# mode:轮廓检索模式
#RETR_EXTERNAL:只检最外面的轮廊
#RETR_LIST:检索所有的轮廊,并将其保存到一条链表当中
#RETR_CCOMP:检索所有的轮廓,并将他们组织为两层:顶层是各部份的外部边界,第二层是空洞的边界
#RETR_TREE:检索所有的轮廓,并重构嵌套轮廓的整个层次
# method:轮廓逼近方法
#CHAIN_APPROX_NONE:以Freeman链码的方式输出轮廓,所有其他方法输出多边形(顶点的序列)。
#CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部,也就是,函数只保留他们的终点部分。
#为了更高的准确率,使用二值图像

def cv_show(name, img):
    cv2.imshow(name, img)  # 显示图像
    cv2.waitKey(0)         # 等待时间,单位毫秒,0表示任意键终止
    cv2.destroyAllWindows()

#1.读取图像
image = cv2.imread("C:\\Users\\zhangqs\\Desktop\\cv.png")

#2.预处理
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)                 #灰度图
ret,threshold=cv2.threshold(gray,160,255,cv2.THRESH_BINARY) #阈值处理

#3.查找轮廓
contours,hierarchy=cv2.findContours(threshold,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

print('共找到',len(contours),'个轮廓')
#4.绘制轮廓

#在原图上绘制轮廓
draw2=image.copy() #注意:需要copy一下,否则将会改动原图
drawed2=cv2.drawContours(draw2,contours,-1,(0,0,255),2)  #图像,轮廓,轮廓索引,颜色模式,线条厚度
cv_show('draw_contours',draw2)

#在灰度图上绘制轮廓(下面的np.hstack函数要求数组维度一致,才能比较显示)
draw=gray.copy() #注意:需要copy一下,否则将会改动原图
drawed=cv2.drawContours(draw,contours,-1,(0,0,255),2)  #图像,轮廓,轮廓索引,颜色模式,线条厚度

#5.轮廓近似

#外接矩形(绿色线)
cnt=contours[12]
# epsilon=0.1*cv2.arcLength(cnt,True)
# approx=cv2.approxPolyDP(cnt,epsilon,True)
x,y,w,h=cv2.boundingRect(cnt)
imgRectangle=cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)
cv_show('Rectangle',imgRectangle)

area=cv2.contourArea(cnt) #轮廓面积
rectArea=w*h #外接矩形面积
rate=float(area)/rectArea
print('轮廓面积/外接矩形面积比:',rate)

#外接圆(蓝色线)
cnt2=contours[11] 
(x,y),radius=cv2.minEnclosingCircle(cnt2)
center=(int(x),int(y))
radius=int(radius)
imgCircle=cv2.circle(image,center,radius,(255,0,0),2)
cv_show('Circle',imgCircle)
areaCircle=cv2.contourArea(cnt) #轮廓面积
rectArea=math.pi*radius*radius #外接圆面积
rateCircle=float(areaCircle)/areaCircle
print('轮廓面积/外接圆面积比:',rateCircle)


# #合并显示
# res=np.hstack((gray,threshold,drawed)) #注意:两层括号
# cv2.imshow('all',res)
# cv2.waitKey(0)
# cv2.destroyAllWindows()


演算結果

 元の画像 

等高線描画 

外接する四角形(緑の線) 

 外接円(青線)

 等高線を走査し、面積比を計算することで、等高線の特徴を見つけ、関心のある等高線をフィルターで除外することができます。

おすすめ

転載: blog.csdn.net/a497785609/article/details/131247819