本帖最后由 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[x, y] = colorIndex
points.remove((x, y)) # 减小外层循环次数
# 检查八领域,如果有未着色的边界点(当然可以写循环)
if(canny_img[x-1, y-1] == 255):
addEllipseColor(x-1, y-1)
if(canny_img[x, y-1] == 255):
addEllipseColor(x, y-1)
if(canny_img[x+1, y-1] == 255):
addEllipseColor(x+1, y-1)
if(canny_img[x, y-1] == 255):
addEllipseColor(x, y-1)
if(canny_img[x, y+1] == 255):
addEllipseColor(x, y+1)
if(canny_img[x+1, y-1] == 255):
addEllipseColor(x+1, y-1)
if(canny_img[x+1, y] == 255):
addEllipseColor(x+1, y)
if(canny_img[x+1, y+1] == 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[0], lt[1]))
for point in points:
colorIndex += colorStep # 换个颜色,继续给下个椭圆着色
addEllipseColor(point[0], point[1])
# 运行到这里,理论上已经给一个椭圆完整的着色了
# 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[0].mean()), int(border[1].mean())
print("(%d, %d)" % (x, y))
cv.circle(img, (x, y), 5, [0, 0, 255], -1) # 在图上画点
colorIndex -= colorStep
cv.imshow("img", img)
cv.waitKey(0)
|