如何识别这个圆边?

时间:2016-09-19 04:52:51

标签: python-2.7 opencv image-processing opencv3.0

我正在尝试使用Python中的OpenCV识别此图片中的圆圈:

我使用网络摄像头拍摄了这张照片。 此灰色圆圈内还有一个徽标。该徽标具有相同颜色的圆圈外部(黑色)

我想将这个灰色圆圈和黑色背景分开并在圆圈周围绘制一条清晰的线条。

我该怎么办?

3 个答案:

答案 0 :(得分:0)

建议: 将图像转换为灰度图像,并使用霍夫圆变换检测圆。 opencv3.0.0 documentation中显示了一个示例。

答案 1 :(得分:0)

以下是您如何实现这一目标: 首先是你的阈值图像,然后你使用查找坐标函数,返回列表的最大值将是你的圆圈。找到峰值并通过它们绘制圆圈。

import cv2 
import numpy as np
import random
from random import randint
import math

image=cv2.imread('C:/Users/srlatch/Desktop/XtfWR.jpg')
img = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)


def f(list):
    max=[]
    for i in list:
        if len(i)>len(max):
            max=i
    return max 

def draw_circle(img,ctr):
    for i in ctr:
        img[i[0][1]][i[0][0]]=255


ret,tresh = cv2.threshold(img,40,255,cv2.THRESH_BINARY)
kernel = np.ones((5,5),np.uint8)
cv2.erode(img,kernel,iterations=2)
tresh,c,hr=cv2.findContours(tresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
circle=f(c)


max_y=0

min_y=circle[0][0][1]

max_x=0

min_x=circle[0][0][0]


pointY=tuple()
pointy=tuple()
pointX=tuple()
pointx=tuple()


for i in circle:
    if i[0][1]>max_y: 
      max_y=i[0][1]
      pointY=(i[0][1], i[0][0])

for i in circle:
    if i[0][1]<=min_y: 
      min_y=i[0][1]
      pointy=(i[0][1], i[0][0])

for i in circle:
    if i[0][0]>max_x: 
      max_x=i[0][0]
      pointX=(i[0][1], i[0][0])

for i in circle:
    if i[0][0]<=min_x: 
      min_x=i[0][0]
      pointx=(i[0][1], i[0][0])

cv2.ellipse(image, (pointY[1],pointY[0]),(2,2),0,0,360,(243,0,214),-1)  #min y
cv2.ellipse(image, (pointy[1],pointy[0]),(2,2),0,0,360,(243,0,214),-1)  #max y
cv2.ellipse(image, (pointX[1],pointX[0]),(2,2),0,0,360,(243,0,214),-1)  #min y
cv2.ellipse(image, (pointx[1],pointx[0]),(2,2),0,0,360,(243,0,214),-1)  #min y

center_x=(pointX[0]+pointx[0])/2
center_y=( (pointY[1]+pointy[1])/2 )-pointy[0]

cv2.circle(image, (int(center_x),int(center_y)), int((center_y+pointy[0])-60),(243,0,214), thickness=1, lineType=8, shift=0)

cv2.imshow('wnd', image)

cv2.waitKey(0)

轮廓发现的结果:

enter image description here

最高和最低分:

enter image description here

盘旋点:

enter image description here

祝你好运!

答案 2 :(得分:0)

另一种方法可能是使用中值滤波器过滤图像。它可以降低噪音并保护边缘。之后,您可以使用固定的threshold(您有一个很好的双峰直方图)进行二值化,然后执行findContours。然后,您可以计算minEnclosingCircle或使用fitEllipse或您想要实现的任何内容。

# Blur the image to supress artefacts
# in the binary image while preserving edges
median = cv2.medianBlur(imgray,15)
# Do a global thresholding
ret, thresh = cv2.threshold(median,0,255,cv2.THRESH_BINARY + cv2.THRESH_OTSU)

#Copy image to show binary image (findContours maipulates source)
copy =thresh.copy()

#Detect just external contours
im2, contours, hierarchy = cv2.findContours(copy, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
height, width, channels = src.shape

#Image for displaying contour
drawing = np.zeros((height, width, 3), dtype='uint8')

#No loop needed, just one external contour
#Draw contour, minimal enclosing circle and ellispe
cv2.drawContours(drawing,contours,0,(255,0,0))
(x,y), radius = cv2.minEnclosingCircle(contours[0])
center = (int(x),int(y))
cv2.circle(drawing,center,int(radius),(0,0,255))
ellipse = cv2.fitEllipse(contours[0])
cv2.ellipse(drawing,ellipse,(0,255,0),1)

cv2.imshow("Binary", thresh)
cv2.imshow("Median", median)
cv2.imshow("Contour", drawing)

![enter image description here

histogram after filtering

![enter image description here

以下是蓝色中的轮廓,红色中的minEnclosingCircle和绿色中的椭圆的结果。

enter image description here