使用 Opencv 检测半圆 Python
Detecting A Half Circle Using Opencv Python
我正在尝试使用 python opencv 检测下图中的半圆角:
以下是我想要实现的目标:(已编辑图片)
我想精确检测半圆 a
我已经使用了轮廓检测,但它也没有很好地工作,这是它的代码:
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()
图像结果如下:
如何准确地检测半圆(准确)以及如何找到半圆的中心并画一条垂直线
这是 Python/OpenCV/Skimage 中的一种方法。
想法是使用一些高斯模糊。然后用kmeans处理得到3种颜色。然后阈值得到中间的颜色,并用一些关闭和打开的形态清理它。然后获取轮廓并绘制在输入上。
输入:
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)
高斯模糊和 Kmeans 图像:
阈值化和形态学清理图像:
输入轮廓:
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)
只要运行上面的代码就是这样一个跟踪框
然后你可以只使用图像检测功能
原图
颜色调整
我正在尝试使用 python opencv 检测下图中的半圆角:
以下是我想要实现的目标:(已编辑图片)
我已经使用了轮廓检测,但它也没有很好地工作,这是它的代码:
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()
图像结果如下:
如何准确地检测半圆(准确)以及如何找到半圆的中心并画一条垂直线
这是 Python/OpenCV/Skimage 中的一种方法。
想法是使用一些高斯模糊。然后用kmeans处理得到3种颜色。然后阈值得到中间的颜色,并用一些关闭和打开的形态清理它。然后获取轮廓并绘制在输入上。
输入:
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)
高斯模糊和 Kmeans 图像:
阈值化和形态学清理图像:
输入轮廓:
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)
只要运行上面的代码就是这样一个跟踪框