作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在尝试从一本书的一堆页面中构建一个数据集。我想将页面中的蝴蝶提取到它们自己的图像中。
例子,
我做了一堆谷歌搜索,只找到了模板匹配,但这似乎只适用于相同类型的图像。另外,由于背景非常稀疏,页面上真的没有其他东西,我想我可以使用它。我认为生成的图像必须重叠,但我最终还需要移除重叠并将图像居中,但我认为我可以做到。
有没有办法首先得到蝴蝶?
最佳答案
我没有像评论中建议的那样使用阈值,而是使用 Canny 边缘检测来寻找蝴蝶,因为它们中的一些在靠近边缘的翅膀上有 Blob ,并且与书的背景颜色相同,这可能会导致获取整个蝴蝶的问题翅膀。此外,由于图像非常大,边缘检测在这里似乎非常可靠。
该方法本身非常简单(我使用 Python 和 OpenCV 来实现):
import cv2
import numpy as np
import platform # Only needed for system information
from skimage import io # Only needed for image web grabbing
# Read image from web; enforce BGR color ordering
image = cv2.cvtColor(io.imread('/image/bwS3g.jpg'),
cv2.COLOR_RGB2BGR)
# Canny edge detection
canny = cv2.Canny(image, 50, 150)
canny = cv2.morphologyEx(canny, cv2.MORPH_CLOSE,
cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))
# Find contours; use proper return value with respect to OpenCV version
cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
# Filter contours with sufficient areas; create binary mask from them
cnts = [c for c in cnts if cv2.contourArea(c) > 10000]
mask = np.zeros_like(canny)
mask = cv2.drawContours(mask, np.array(cnts), -1, 255, cv2.FILLED)
# Iterate all contours...
for i, c in enumerate(cnts):
# Get bounding rectangle of contour and min/max coordinates
rect = cv2.boundingRect(c)
(x1, y1) = rect[:2]
x2 = x1 + rect[2]
y2 = y1 + rect[3]
# Get image section
crop_image = image[y1:y2, x1:x2]
# Get mask section and cut possible neighbouring contours
crop_mask = mask[y1:y2, x1:x2].copy()
cnts = cv2.findContours(crop_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
c = max(cnts, key=cv2.contourArea)
crop_mask[:, :] = 0
cv2.drawContours(crop_mask, [c], -1, 255, cv2.FILLED)
# Create butterfly image with transparent background
butterfly = np.zeros((rect[3], rect[2], 4), np.uint8)
butterfly[:, :, :3] = cv2.bitwise_and(crop_image, crop_image,
mask=crop_mask)
butterfly[:, :, 3] = crop_mask
cv2.imwrite(str(i) + '.png', butterfly)
print('------------------')
print('System information')
print('------------------')
print('Python: ', platform.python_version())
print('NumPy: ', np.__version__)
print('OpenCV: ', cv2.__version__)
print('------------------')
------------------
System information
------------------
Python: 3.7.1
NumPy: 1.18.1
OpenCV: 4.1.2
------------------
关于opencv - 如何从一本书的页面中提取一堆图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59641546/
我是一名优秀的程序员,十分优秀!