简体   繁体   中英

Detecting A Half Circle Using Opencv Python

I am trying to detect a semi cricle in the following image using python opencv: 在此处输入图像描述

Following is what i am trying to achieve: (Edited Image ) 在此处输入图像描述 I want to exactly detect the semicircle a

I have used contour detection but it also hasn't work that well here is the code for that:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('images/m_1.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.blur(img,(5,5))

lower = np.array([60,60,60])
higher = np.array([80,80,80])

mask = cv2.inRange(img,lower,higher)

cont,_ = cv2.findContours(mask,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
cont_img = cv2.drawContours(img,cont,-1,255,3)
plt.imshow(cont_img)

#plt.imshow(img)

plt.show()

Following is the result of the image: 在此处输入图像描述

How can i accurately detect a the semi circle (Accurately ) and also optional is how can i find the centre of the semicircle and draw a vertical line

Here is one way to do that in Python/OpenCV/Skimage.

The idea is to use some Gaussian blur. Then use kmeans processing to get 3 colors. Then threshold to get the middle color and clean it up with some morphology close and open. Then get the contour and draw it on the input.

Input:

在此处输入图像描述

import cv2
import numpy as np
from sklearn import cluster

# read input
image = cv2.imread('semi_circle.png')
h, w = image.shape[:2]

# convert to gray in range 0 to 1
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY).astype(np.float32)/255

# Gaussian blur gray image
gray_blur = cv2.GaussianBlur(gray, (0,0), sigmaX=3, sigmaY=3)

# reshape to 1D array
image_1d = gray_blur.reshape(h*w,1)

# set number of colors
numcolors = 3

# do kmeans processing
kmeans_cluster = cluster.KMeans(n_clusters=int(numcolors))
kmeans_cluster.fit(image_1d)
cluster_centers = kmeans_cluster.cluster_centers_
cluster_labels = kmeans_cluster.labels_

# need to scale result back to range 0-255
newimage = cluster_centers[cluster_labels].reshape(h, w)*255.0
newimage = newimage.astype('uint8')

# threshold to keep only mid gray values
lower = (75)
upper = (150)
thresh = cv2.inRange(newimage, lower, upper)

# use morphology to clean up
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (13,13))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (19,19))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)

# get largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# draw contour on input
result = image.copy()
cv2.drawContours(result, [big_contour], 0, (0,0,255), 1)

# display result
cv2.imshow('newimage', newimage)
cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('semi_circle_kmeans.png', newimage)
cv2.imwrite('semi_circle_thresh.png', thresh)
cv2.imwrite('semi_circle_result.png', result)

Gaussian Blur and Kmeans Image:

在此处输入图像描述

Thresholded and Morphology Cleaned Image:

在此处输入图像描述

Contour on Input:

在此处输入图像描述

import cv2
import numpy as np

def empty(a):
    pass


path = 'media/USrSO.png'
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",116,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",0,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",201,255,empty)
cv2.createTrackbar("Val Min","TrackBars",157,255,empty)
cv2.createTrackbar("Val Max","TrackBars",255,255,empty)

while True:
    img = cv2.imread(path)
    imgHSV = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
    h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
    h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
    s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
    s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
    v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
    v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
    print(h_min,h_max,s_min,s_max,v_min,v_max)
    lower = np.array([h_min,s_min,v_min])
    upper = np.array([h_max,s_max,v_max])
    mask = cv2.inRange(imgHSV,lower,upper)
    imgResult = cv2.bitwise_and(img,img,mask=mask)

    cv2.imshow("Track Images", imgResult)
    cv2.imshow("Original Images", img)

    cv2.waitKey(1)

Just run the above code a tracker box like this在此处输入图像描述 Then you can a just use a image detection capability Original image在此处输入图像描述 Color adjusted
在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM