使用opencv将图像的轮廓提取为连续路径
Extracting the outline of an image as a continuous path using opencv
背景
所以我目前正在从事一个项目,该项目是编码列车的傅立叶变换系列的扩展。非常感谢他启发了这个项目!
在观看了他关于编码火车徽标的傅立叶变换的视频后,我认为尝试对任何图像实施此操作会很有趣。我的目标是能够将任何图像中的主体轮廓作为连续路径提供给 DFT 算法,以便我可以可视化所述路径的傅里叶变换。
Link 编码火车的视频:https://www.youtube.com/watch?v=MY4luNgGfms
我的进步
到目前为止,在 python 中使用 opencv,我已经实现了一种算法,可以从任何图像中检测主体的轮廓并显示出来。我附上了示例输出。
处理前
Image before processing
处理后
Image after processing
我的问题和预期结果
现在我已经完成了边缘,我希望能够将此边缘提取为由 (x,y) 坐标表示的连续路径。我需要它作为连续路径的原因是我要在这条路径上执行 DFT,如果它不连续,我的 DFT 可视化就会失败。
我不知道如何对点进行排序,使它们不会从左到右或从上到下跳转,而是沿着从左到右的平滑连续路径,反之亦然。
我是计算机视觉的初学者,我真的希望有人能帮助我!如果我在某个地方搞砸了或者我是否可以改进我的代码,请随时告诉我。好想学
代码
到目前为止,这是我的代码
img = cv2.imread("Images/selfietest.jpeg")
# convert image to gray scale
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
height, width = gray_img.shape
# white_padding = np.zeros((50, width, 3))
# white_padding[:, :] = [255, 255, 255]
# rgb_img = np.row_stack((white_padding, imgOut))
gray_img = 255 - gray_img
gray_img[gray_img > 100] = 255
gray_img[gray_img <= 100] = 0
# black_padding = np.zeros((50, width))
# gray_img = np.row_stack((black_padding, gray_img))
kernel = np.ones((30, 30), np.uint8)
# fill inside of image
filledImage = cv2.morphologyEx(gray_img, cv2.MORPH_CLOSE, kernel)
filledImageNormalized = np.uint8(filledImage)
#Canny edge detection
edges = cv2.Canny(filledImageNormalized, 100, 200)
title = ['edges']
images = [edges]
for i in range(1):
plt.subplot(1, 1, i + 1), plt.imshow(images[i], 'gray')
plt.title(title[i])
plt.xticks([])
plt.yticks([])
plt.show()```
让我做一个假设:您只使用提供的图像。假设起点是最后一行的白色像素。该方法将是:
- 从起点开始,顺时针看一个8邻域,从南邻开始
- 检查邻居是不是白人。
- 如果是,存储,并设置为新的起点,重启进程
- 如果不是,看看下一个邻居
- 继续,直到到达一个没有更多白色像素邻居的像素。
话虽如此,也许您不仅仅处理这张图片。在那种情况下,您必须调整查找起始像素的方式以匹配所有可能性。
但是有了这个,你的轮廓就会有一条连续的路径。
背景
所以我目前正在从事一个项目,该项目是编码列车的傅立叶变换系列的扩展。非常感谢他启发了这个项目!
在观看了他关于编码火车徽标的傅立叶变换的视频后,我认为尝试对任何图像实施此操作会很有趣。我的目标是能够将任何图像中的主体轮廓作为连续路径提供给 DFT 算法,以便我可以可视化所述路径的傅里叶变换。
Link 编码火车的视频:https://www.youtube.com/watch?v=MY4luNgGfms
我的进步
到目前为止,在 python 中使用 opencv,我已经实现了一种算法,可以从任何图像中检测主体的轮廓并显示出来。我附上了示例输出。
处理前 Image before processing
处理后 Image after processing
我的问题和预期结果
现在我已经完成了边缘,我希望能够将此边缘提取为由 (x,y) 坐标表示的连续路径。我需要它作为连续路径的原因是我要在这条路径上执行 DFT,如果它不连续,我的 DFT 可视化就会失败。
我不知道如何对点进行排序,使它们不会从左到右或从上到下跳转,而是沿着从左到右的平滑连续路径,反之亦然。
我是计算机视觉的初学者,我真的希望有人能帮助我!如果我在某个地方搞砸了或者我是否可以改进我的代码,请随时告诉我。好想学
代码
到目前为止,这是我的代码
img = cv2.imread("Images/selfietest.jpeg")
# convert image to gray scale
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
height, width = gray_img.shape
# white_padding = np.zeros((50, width, 3))
# white_padding[:, :] = [255, 255, 255]
# rgb_img = np.row_stack((white_padding, imgOut))
gray_img = 255 - gray_img
gray_img[gray_img > 100] = 255
gray_img[gray_img <= 100] = 0
# black_padding = np.zeros((50, width))
# gray_img = np.row_stack((black_padding, gray_img))
kernel = np.ones((30, 30), np.uint8)
# fill inside of image
filledImage = cv2.morphologyEx(gray_img, cv2.MORPH_CLOSE, kernel)
filledImageNormalized = np.uint8(filledImage)
#Canny edge detection
edges = cv2.Canny(filledImageNormalized, 100, 200)
title = ['edges']
images = [edges]
for i in range(1):
plt.subplot(1, 1, i + 1), plt.imshow(images[i], 'gray')
plt.title(title[i])
plt.xticks([])
plt.yticks([])
plt.show()```
让我做一个假设:您只使用提供的图像。假设起点是最后一行的白色像素。该方法将是:
- 从起点开始,顺时针看一个8邻域,从南邻开始
- 检查邻居是不是白人。
- 如果是,存储,并设置为新的起点,重启进程
- 如果不是,看看下一个邻居
- 继续,直到到达一个没有更多白色像素邻居的像素。
话虽如此,也许您不仅仅处理这张图片。在那种情况下,您必须调整查找起始像素的方式以匹配所有可能性。
但是有了这个,你的轮廓就会有一条连续的路径。