|

楼主 |
发表于 2022-3-7 19:08:52
|
显示全部楼层
本帖最后由 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)
复制代码 |
|