【发布时间】:2019-08-09 05:26:19
【问题描述】:
我有一张来自手机的 Instagram 屏幕截图,我想只自动提取主图像,去掉所有环境和文字。我正在考虑边缘检测或霍夫变换,任何优雅而简单的解决方案?
请注意,图像可能并不总是居中,有时它只显示部分,如下例所示。
谢谢!!
示例图片:
【问题讨论】:
标签: python opencv image-processing computer-vision edge-detection
我有一张来自手机的 Instagram 屏幕截图,我想只自动提取主图像,去掉所有环境和文字。我正在考虑边缘检测或霍夫变换,任何优雅而简单的解决方案?
请注意,图像可能并不总是居中,有时它只显示部分,如下例所示。
谢谢!!
示例图片:
【问题讨论】:
标签: python opencv image-processing computer-vision edge-detection
这是一个使用 OpenCV Python 的简单方法
Canny 边缘检测(左)然后执行形态变换以平滑图像(右)
canny = cv2.Canny(gray, 5, 150, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel, iterations=2)
现在我们找到轮廓并按最大轮廓区域排序。这个想法是最大的轮廓将是主图像。即使图像没有居中,也应该是最大的区域。一个额外的过滤步骤可能是添加aspect ratio 以确保轮廓是正方形/矩形。
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
ROI = original[y:y+h, x:x+w]
break
最后提取ROI,我们可以使用Numpy slicing
代码
import cv2
image = cv2.imread('2.jpg')
original = image.copy()
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
canny = cv2.Canny(gray, 5, 150, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = cv2.morphologyEx(canny, cv2.MORPH_CLOSE, kernel, iterations=2)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
ROI = original[y:y+h, x:x+w]
break
cv2.imshow('canny', canny)
cv2.imshow('close', close)
cv2.imshow('image', image)
cv2.imshow('ROI', ROI)
cv2.imwrite('canny.png', canny)
cv2.imwrite('close.png', close)
cv2.imwrite('ROI.png', ROI)
cv2.imwrite('image.png', image)
cv2.waitKey(0)
【讨论】: