如何提取图片中的椭圆中心
本帖最后由 King丨小义 于 2022-3-4 08:29 编辑求助关于数字图像处理的一个问题{:5_92:}
如图所示,图片中有若干椭圆,如何提取出椭圆的中心坐标(不需要知道椭圆的长半轴参数)
目前我的想法是先通过梯度算子将边缘提取出来,对于只有一个椭圆的图像,我可以通过对边缘的所有像素点求平均值来提取椭圆中心坐标。
但是对于一张图中有多个椭圆的情况,提取过程中就需要告诉程序如何分辨多个椭圆。
求问各位大佬有什么好的想法?对于提取这张图片的椭圆的中心坐标?
最好使用Python + OpenCV(别的语言也可以) 本帖最后由 King丨小义 于 2022-3-7 19:09 编辑
我已经有一个思路了。具体算法如下:
1. 对图像使用Canny边缘检测(其实不检测也可以,个人感觉检测之后算法效率会高,虽然没有比较过)
2. 寻找第一个边缘点,给该点上一种颜色
3. 然后从该点出发,寻找其八领域内的下一个没有上过色的边缘点
4. 重复2-3步(没错,我要开始递归了)
5. 到此为止,理论上已经给不同的椭圆上不同的色了,接下来就可以根据颜色区分不同椭圆,然后对边缘求平均值得到中心点坐标
该算法默认椭圆不相交不粘连(基本够我用了)
代码如下,图片在本帖提问处。
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
def addEllipseColor(x, y):
canny_img = colorIndex
points.remove((x, y))# 减小外层循环次数
# 检查八领域,如果有未着色的边界点(当然可以写循环)
if(canny_img == 255):
addEllipseColor(x-1, y-1)
if(canny_img == 255):
addEllipseColor(x, y-1)
if(canny_img == 255):
addEllipseColor(x+1, y-1)
if(canny_img == 255):
addEllipseColor(x, y-1)
if(canny_img == 255):
addEllipseColor(x, y+1)
if(canny_img == 255):
addEllipseColor(x+1, y-1)
if(canny_img == 255):
addEllipseColor(x+1, y)
if(canny_img == 255):
addEllipseColor(x+1, y+1)
if __name__ == "__main__":
img = cv.imread("./test.jpg")
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
x, y = gray.shape
colorIndex = 0
colorStep = 80 # 颜色增量(当然可以调成最低1,这里调80只是为了下面可以观察颜色赋值情况)
canny_img = cv.Canny(gray, 0, 100)
# cv.imshow("img", canny_img)
# cv.waitKey(0)
lt = np.where(canny_img == 255)
points = list(zip(lt, lt))
for point in points:
colorIndex += colorStep# 换个颜色,继续给下个椭圆着色
addEllipseColor(point, point)
# 运行到这里,理论上已经给一个椭圆完整的着色了
# cv.imshow("canny_img", canny_img)
# cv.waitKey(0)
# 例如 colorIndex = 240 代表检测到了3个椭圆
while colorIndex != 0:
border = np.where(canny_img == colorIndex)
y, x = int(border.mean()), int(border.mean())
print("(%d, %d)" % (x, y))
cv.circle(img, (x, y), 5, , -1)# 在图上画点
colorIndex -= colorStep
cv.imshow("img", img)
cv.waitKey(0)
可不可以这样啊,边缘知道了,就可以求出斜率,找到斜率为0的位置,和斜率不存在的位置,四个点交点就是中点 本帖最后由 King丨小义 于 2022-3-4 08:17 编辑
Python初学者8号 发表于 2022-3-3 22:44
可不可以这样啊,边缘知道了,就可以求出斜率,找到斜率为0的位置,和斜率不存在的位置,四个点交点就是中 ...
感觉不能识别多个椭圆哎,而且算法复杂度还不如求所有边缘点的均值。
并且椭圆不是正放的,有一点倾斜度,这个算法有点问题吧。(虽然结果是对的,因为根据对称性,只要找出一对对称的点,就可以求出中点) King丨小义 发表于 2022-3-4 08:12
感觉不能识别多个椭圆哎,而且算法复杂度还不如求所有边缘点的均值。
并且椭圆不是正放的,有一点倾斜 ...
我也来提供一个思路,
1.用数组找宽度最长行,
2用数组找高度最长列,
3.计算他们交叉点? z5560636 发表于 2022-3-4 13:41
我也来提供一个思路,
1.用数组找宽度最长行,
2用数组找高度最长列,
没听懂哎,感觉和楼上那位求斜率为0和斜率不存在的差不多哎 King丨小义 发表于 2022-3-4 08:12
感觉不能识别多个椭圆哎,而且算法复杂度还不如求所有边缘点的均值。
并且椭圆不是正放的,有一点倾斜 ...
我草,倾斜度,这个,有点复杂了。我也琢磨琢磨{:10_266:}
页:
[1]