7. OpenCV - Contorno de imagen

1. A través de findContours de OpenCV, puede encontrar fácilmente el contorno del contenido de la imagen.

2. Para tener una mayor precisión en la extracción del contorno, antes de extraer el contorno, es necesario preprocesar la imagen (valor binario + umbral), y mantener solo la imagen de interés.

3. Al calcular el área del contorno y el área del rectángulo circunscrito o círculo circunscrito, se pueden encontrar las características del contorno y los contornos de interés se pueden filtrar aún más.

Sintaxis: cv2.findContours(img,modo,método)
modo: modo de recuperación de contornos
RETR_EXTERNAL: solo verifica los contornos más externos
RETR_LIST: recupera todos los contornos y los guarda en una lista enlazada RETR_CCOMP: recupera todos los contornos y los organiza en dos
capas: la capa superior es el límite exterior de cada parte, la segunda capa es el límite del agujero RETR_TREE: recupera todos los contornos y reconstruye la jerarquía completa de contornos anidados (Esto es comúnmente utilizado): método de aproximación de contorno CHAIN_APPROX_NONE: salida de contorno en forma de código de cadena Freeman, todos los demás métodos generan polígonos (secuencias
de
vértices )
.
CHAIN_APPROX_SIMPLE: Comprime partes horizontales, verticales y oblicuas, es decir, la función conserva solo sus partes finales.
Para una mayor precisión, utilice imágenes binarias

Código de muestra 

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()


resultado de la operación

 imagen original 

Dibujo de contorno 

Rectángulo delimitador (línea verde) 

 Círculo circunscrito (línea azul)

 Al atravesar el contorno, al calcular la relación del área, podemos encontrar las características del contorno y luego filtrar los contornos que nos interesan.

Supongo que te gusta

Origin blog.csdn.net/a497785609/article/details/131247819
Recomendado
Clasificación