2016-09-19 155 views
1

我試圖找出使用Python中的OpenCV這幅畫的圓圈:如何識別這個圓形邊緣?

我使用網絡攝像頭,這一形象。 這個灰色圓圈裏面還有一個標誌。這個標誌有相同顏色的圓圈外圈(黑色)

我想把這個灰色圓圈和黑色背景分開,並在圓圈周圍劃一條銳利的線條。

我該怎麼辦?

回答

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

+0

好主意..可以我可以讓你的信息,以提高我的碼。謝謝 – NSiri

+0

你的意思是代碼? – PSchn

+0

不,你已經添加了唯一的想法first.Then你已經編輯了答案...所以,我的意思只是想法......無論如何,我使用Python ..所以,我需要轉換你的代碼。謝謝 – NSiri

0

建議: 將圖像轉換爲灰度圖像並使用Hough Circle Transform來檢測圓。 一個示例顯示在opencv3.0.0 documentation中。

+0

霍夫圈是不是我的要求,一個好的系統...感謝想法.. – NSiri

+0

我想檢測上有攝像頭輸入一個圓或不exactly.using霍夫Circle方法我能檢測圓有一些晃動(檢測到的圓正在晃動。這不是一個大問題..但是,我想檢測到有一個圓或不完全...我怎樣才能使用霍夫圓檢測方法存檔我的目標? – NSiri

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

祝你好運!

+0

感謝您的代碼示例。什麼是max_y_f()函數? – NSiri

+0

最大最小功能下的圖片,我只是刪除函數定義 –

+0

我更新的代碼,所以你可以更好地看到它 –