因此,我对opencv并不陌生,我想从图像中提取移动电话对象,并对它进行透视变换,以便能够以鸟瞰图的形式查看它。我在网上找到了很多文章,但似乎没有任何帮助。 这是Original Image
的链接我要执行的操作将手机从其中取出。手机屏幕将始终为绿色,因此应该很容易检测矩形的边缘。我能够使用遮罩将电话本身从中提取出来。我面临的问题是进行透视转换,以使其在屏幕上直接对齐。
def get_green_mask(img):
sensitivity = 20
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_green = np.array([60-sensitivity, 100, 100])
upper_green = np.array([60+sensitivity, 255, 255])
return cv2.inRange(hsv, lower_green, upper_green)
def process_image(img_filename):
img = cv2.imread(img_filename)
green_mask = get_green_mask(img)
temp, contours, _ = cv2.findContours(green_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contour = np.array(0)
for c in contours:
if c.size > contour.size:
contour = c
img2 = np.copy(img)
cv2.drawContours(img2, contour, -1, (0,0,255), 20)
## (3) morph-op to remove horizone lines
kernel = np.ones((5,1), np.uint8)
mask2 = cv2.morphologyEx(green_mask, cv2.MORPH_OPEN, kernel)
## (4) crop the region
ys, xs = np.nonzero(mask2)
ymin, ymax = ys.min(), ys.max()
xmin, xmax = xs.min(), xs.max()
screen = img[ymin+8:ymax-8, xmin+8:xmax-8]
green_mask2 = get_green_mask(screen)
target = cv2.bitwise_and(screen,screen, mask=green_mask2)
fig, axes = plt.subplots(1, 4, figsize = (14,6))
#counter drawn
axes[0].imshow(img2, interpolation='nearest', aspect='auto')
#mask of the image
axes[1].imshow(green_mask, interpolation='nearest', aspect='auto')
#the screen without second mask
axes[2].imshow(screen, interpolation='nearest', aspect='auto')
#second mask to remove noise
axes[3].imshow(target, interpolation='nearest', aspect='auto')
return target
代码非常简单。 process_image接收文件名,然后从其中提取电话对象。我也不确定这是否是提取电话对象的最佳方法,如果我错了,请随时纠正我。
有关鸟瞰视角转换的问题:
包含电话的图像只是一个例子,每次用户拍摄新照片时,图像可能会有所不同。我的意思是,手机的坐标和位置在不同的图像中会有所不同,因此我正在寻找可靠的解决方案。
我希望我清楚地问这个问题!帮助将不胜感激! :) 谢谢!