OpenCV检测毛巾边缘

4
使用Python和OpenCV找到毛巾图像中最低角(而非边缘)的最佳方法是什么?此外,毛巾的颜色可能不同,但背景颜色始终相同。

towel

我需要这个角落(最低的“真正”的毛巾角落): 期望结果


1
你的意思是“毛巾的边缘”吗? - Jeru Luke
这是什么意思?您想要做什么?请解释您的问题。 - Muhammad Usman
嗨,我需要获取最低角(不是边缘,而是角落)的坐标(x,y)。 - Daniel
3个回答

6

由于您的图像大约有两种不同的颜色(前景和背景各一种),因此您可以将图像转换为HSV颜色空间,并可视化每个单独的通道。

代码:

path = r'C:\Users\Desktop'
filename = 'towel.jpg'

img = cv2.imread(os.path.join(path, filename))    
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)     #--- convert to HSV
cv2.imshow('hsv.jpg', hsv)
h = hsv[:,:,0]
cv2.imshow('h.jpg', h)                         #--- visualize the hue channel

enter image description here

ret, thresh = cv2.threshold(h, 0, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY_INV)
cv2.imshow('thresh1', thresh)                  #--- apply Otsu threshold on hue channel

enter image description here

请注意毛巾中心的白色斑点,它必须被去除。为此,我使用了形态学开运算。

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(25, 25))
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
cv2.imshow('fin', cv2.bitwise_not(opening))

enter image description here

编辑

OpenCV提供了查找给定轮廓的顶部、底部、最右侧和最左侧角点的功能。我获取了最终结果图像的轮廓并找到了四个极点。

代码:

im2, contours, hierarchy = cv2.findContours(cv2.bitwise_not(opening), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)                #--- finding contours
cnt = contours[0]                                 #--- since there is only one contour present

leftmost = tuple(cnt[cnt[:,:,0].argmin()][0])
rightmost = tuple(cnt[cnt[:,:,0].argmax()][0])
topmost = tuple(cnt[cnt[:,:,1].argmin()][0])
bottommost = tuple(cnt[cnt[:,:,1].argmax()][0])

print('The extreme points are leftmost: {}, rightmost: {}, topmost: {} and bottommost: {}'.format(leftmost, rightmost, topmost, bottommost))

The extreme points are leftmost: (32, 336), rightmost: (807, 439), topmost: (459, 12) and bottommost: (699, 743)

我还在原始图像的副本上标记了极端点:

img2 = img.copy()
cv2.circle(img2, leftmost, 5, (0, 255, 255), -1)    #-- leftmost
cv2.circle(img2, rightmost, 5, (0, 255, 255), -1)    #-- rightmost
cv2.circle(img2, topmost, 5, (0, 255, 255), -1)    #-- topmost
cv2.circle(img2, bottommost, 5, (0, 255, 255), -1)    #-- bottommost

enter image description here


非常好的回答,谢谢。但是我如何获取最低角(不是边缘,而是角落)的坐标(x,y)? - Daniel
@Daniel 如果这个回答解决了你的问题,请考虑接受它,以帮助其他用户在未来解决类似问题! - Rick M.
嗨,答案几乎完美。这是一个完美的开始,但我需要找到90度的角落,而不是最底部的点。 - Daniel
@Daniel,你能发布一张带有期望标记的图片吗? - Jeru Luke
1
@JeruLuke,我现在也正在根据你的代码进行一些测试——你给我的起点非常棒。 - Daniel
显示剩余2条评论

0
你需要的是边缘检测算法。
从以下链接使用下面的代码。
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('Your towel image.jpg',0)
edges = cv.Canny(img,100,200)
plt.subplot(121),plt.imshow(img,cmap = 'gray')
plt.title('Original Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(edges,cmap = 'gray')
plt.title('Edge Image'), plt.xticks([]), plt.yticks([])
plt.show()

0
你可以使用Canny边缘检测器来检测图像的角落。我在下面给出了两个来源的链接。 Source1 Source2 代码:
import cv2
import matplotlib.pyplot as plt

im = cv2.imread('boat.png')
edges = cv2.Canny(im,25,255,L2gradient=False)
plt.imshow(edges,cmap='gray')
plt.show()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接