python - 如何使用 OpenCV python 自动检测修剪和裁剪图像的一部分?
问题描述
我正在研究图像到文本的转换程序,我想删除周围不必要的图像、背景和文本,以便它强调我希望从中提取文本的主要区域!
请参阅药盒上的警告标签。如何仅提取图像的预期区域!?因为所有其他元素都会引起噪声并影响提取的准确性。
解决方案
我的建议是找到具有最大子轮廓数的轮廓。
具有最大子节点数的轮廓是其中包含最多字母的轮廓。
这只是粗过滤的第一阶段,还有更多阶段:
- 转换为灰度,并转换为二值图像。
- 查找轮廓和层次结构。
用于RETR_TREE
在轮廓内创建轮廓树。 - 找到具有最大子轮廓数的父轮廓。
- 从图像中裁剪上述轮廓的边界矩形。
- 查找连接的组件(集群)。
- 删除大、小、高和宽的簇——当然不是字母。
- 使用“关闭”形态学操作来合并文本区域。
- 找到轮廓,并裁剪轮廓的最大面积边界矩形。
这个问题具有挑战性,我的回答可能与您发布的图像过拟合。
您可以改进启发式方法以获得更通用的解决方案。
这是代码:
import numpy as np
import cv2
# Read input image
img = cv2.imread('dizziness.jpg')
# Convert to Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Convert to binary image - use THRESH_OTSU for automatic threshold.
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Find contours and hierarchy, use RETR_TREE for creating a tree of contours within contours
cnts, hiers = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[-2:] # [-2:] indexing takes return value before last (due to OpenCV compatibility issues).
# https://docs.opencv.org/master/d9/d8b/tutorial_py_contours_hierarchy.html
# Hierarchy Representation in OpenCV
# So each contour has its own information regarding what hierarchy it is, who is its child, who is its parent etc.
# OpenCV represents it as an array of four values : [Next, Previous, First_Child, Parent]
parent = hiers[0, :, 3]
# Find parent contour with the maximum number of child contours
# Use np.bincount for counting the number of instances of each parent value.
# https://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html#numpy.bincount
hist = np.bincount(np.maximum(parent, 0))
max_n_childs_idx = hist.argmax()
# Get the contour with the maximum child contours
c = cnts[max_n_childs_idx]
# Get bounding rectangle
x, y, w, h = cv2.boundingRect(c)
# Crop the bounding rectangle out of img
img = img[y:y+h, x:x+w, :]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Convert to binary image (after cropping) and invert polarity
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
#cv2.imshow('thresh', thresh);cv2.waitKey(0);cv2.destroyAllWindows()
# Find connected components (clusters)
nlabel,labels,stats,centroids = cv2.connectedComponentsWithStats(thresh, connectivity=8)
# Delete large, small, tall and wide clusters - not letters for sure
max_area = 2000
min_area = 10
max_width = 100
max_height = 100
for i in range(1, nlabel):
if (stats[i, cv2.CC_STAT_AREA] > max_area) or \
(stats[i, cv2.CC_STAT_AREA] < min_area) or \
(stats[i, cv2.CC_STAT_WIDTH] > max_width) or \
(stats[i, cv2.CC_STAT_HEIGHT] > max_height):
thresh[labels == i] = 0
#cv2.imshow('thresh', thresh);cv2.waitKey(0);cv2.destroyAllWindows()
# Use "closing" morphological operation for uniting text area
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, np.ones((50, 50)))
# Find contours once more
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2]
# Get contour with maximum area
c = max(cnts, key=cv2.contourArea)
# Get bounding rectangle
x, y, w, h = cv2.boundingRect(c)
# Crop the bounding rectangle out of img (leave some margins)
out = img[y-5:y+h+5, x-5:x+w+5]
# Show output
cv2.imshow('out', out);
cv2.waitKey(0);
cv2.destroyAllWindows()
推荐阅读
- nhibernate - 将 NHibernate 与 SAP Advantage 数据库服务器 12 一起使用
- vue.js - 在 Vue 2 中使用属性“路由”
- java - FragmentTransaction add 方法接受了错误的参数
- python - 从 Pandas 的日期范围创建随机排序的日期
- android - 使用 Python3 从设备发送照片并通过 TCP 在 Android 设备上接收照片会在 Android 设备上产生 OOM
- python - 使用 matplotlib 沿图表绘制表格
- php - 将 laravel 项目部署到 Azure 时出现 SQL SSL 错误
- node.js - 如何在 Nodejs 中使用 Twilio API 在会议开始时添加“说”消息
- python - 摄像机不会随 cv2.VideoCapture(0).release() 转动
- java - String 类的 split 方法和每个循环都没有给出所需的输出