我有一些草图图像,我的目标是分割子图形或对象。我有原始图像和相应的遮罩图像。我的目标是检测遮罩图像的轮廓,并使用该轮廓信息在原始图像上绘制边界框。我的代码适用于大多数图像。但并非所有图像都适用
附图4:未成功的原始掩码
附图5:未成功的原始图像
附图6:未成功的原始掩码
我的代码:
import cv2
import pytesseract
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle
import os
os.chdir(r'D:\job\LAL\data\data\400_figures\test')
img = cv2.imread('9.jpg') ## original image
img1 = cv2.imread('output_9.jpg') ## masked image
gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
canny_get_edge= cv2.Canny(gray,40,250)
#contours, hierarchy= cv2.findContours(canny_get_edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:]
#contours, hierarchy= cv2.findContours(canny_get_edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(canny_get_edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2:]
cv2.drawContours(img, contours, -1, (0,255,0), 4)
cv2.imshow('Contours', img)
cv2.imwrite('result9.jpg', img)
#os.remove("output.png")
#os.chdir(r'D:\job\LAL\data\data\400_figures\renamed_400_figures')
# Load original image
im = cv2.imread('9.jpg') ## original image
for c in contours:
rect = cv2.boundingRect(c)
if rect[2] < 50 or rect[3] < 50: continue
cv2.contourArea(c)
x, y, w, h = rect
cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(im, 'Detected', (x + w + 10, y + h), 0, 0.3, (0, 255, 0))
cv2.imshow('cc',im)
cv2.imwrite('box9.jpg', im)
这里有一个可能的解决方案。但是,请注意,我不能保证这将适用于您尚未发布的复杂图像。另外,你在互联网上收到陌生人的免费帮助,不要指望一个完整的解决方案能不费吹灰之力就解决你的问题。帮助别人是很酷的,但是请合理地设定你的期望值
该方法涉及获取图像上最大对象的边界框,这些是假设:
如果您对每幅图像处理一个草图和标题,如果一幅图像上有多个图形,这种方法将不会有帮助。您必须手动剪切它们。例如,烧烤架的图像–必须在两个图像中分开
一些图形及其标题不能用矩形分隔–这是因为用四个直角的四边形包围图形也会包围标题,如果后者位于所述四边形区域内(在此方法之前,您必须过滤标题、扩展此方法或使用多边形进行裁剪-这是另一个不同的问题)
该方法包括将图像缩小为水平和垂直投影。我们只需要两个投影的起点和终点,我们应该能够构造一个边界矩形。投影正好(理想情况下)然而,如果人物的标题与投影不重叠,我们可以通过处理最大的投影来过滤掉。这是一种很好的方法,非常适合像烧烤架这样的图像
以下是步骤:
我在这里手动分离了栅格图像:Part 1和Part 2。让我们看看代码:
第一位将图像大小调整为
30
的缩放百分比。这对于您发布的图像来说已经足够了。该过程相当简单,并生成此(缩小的)二值图像:我们可以应用一点形态学将图形的较小部分连接成一个实体组件。让我们应用一个带有
3 x 3
矩形结构元素的closing
(膨胀后侵蚀):结果是:
好的,让我们
reduce
这个图像。我们首先通过减少行得到水平投影,然后通过减少列得到垂直投影模式,其中行/列中的每个像素值定义为对应于该图像行/列的最大强度值计算投影后,我们可以立即过滤图像中的最小直线。我们可以计算
contours
,得到它的“边界矩形”(实际上,矩形是只是一个起点/终点,因为投影只是一条直线)并保留最大的。在此步骤中,我们还可以存储起点/终点:这几乎就是这个过程的肉。这些图像显示了第一张图像的水平和垂直投影
水平的预测:
垂直投影:
注意水平投影上的第二条(较小)线。这与标题相对应,我们的“最大区域过滤器”忽略了标题。所有相关信息都存储在
boundingRectsList
变量中。让我们构造边界矩形,放大信息并在原始的放大输入上显示矩形:这将产生:
烤架的第二个图像:
鞋子的第一张图片:
相关问题 更多 >
编程相关推荐