Opencv 检测并提取由帧包围的图像

Opencv 检测并提取由帧包围的图像,opencv,imagemagick,Opencv,Imagemagick,我想从输入图像中获得以下结果图像。生成的图像由边框大小和类型相同但边框矩形大小不同的边框包围。有没有办法做到这一点?我想我需要首先探测边界周围的区域。但是不知道。我想在ImageMagick中找到它 输入图像(Input.png) 结果图像(output1.png) 结果图像(output2.png) 边界 更新1 这并不完美,但它与OpenCV一起工作,如下所示 import cv2 as cv def main(): image_file = '/path

我想从输入图像中获得以下结果图像。生成的图像由边框大小和类型相同但边框矩形大小不同的边框包围。有没有办法做到这一点?我想我需要首先探测边界周围的区域。但是不知道。我想在ImageMagick中找到它

  • 输入图像(Input.png)

  • 结果图像(output1.png)

  • 结果图像(output2.png)

  • 边界


更新1

这并不完美,但它与OpenCV一起工作,如下所示

import cv2 as cv

def main():
    image_file = '/path/to/your/input/image.png'
    src = cv.imread(image_file, cv.IMREAD_COLOR)
    height, width, channels = src.shape
    image_size = height * width
    img_gray = cv.cvtColor(src, cv.COLOR_RGB2GRAY)
    retval, dst = cv.threshold(img_gray, 1000, 255, cv.THRESH_TOZERO_INV)
    dst = cv.bitwise_not(dst)
    retval, dst = cv.threshold(dst, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    dst, contours, hierarchy = cv.findContours(
        dst, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

    xxx = 0
    for i, contour in enumerate(contours):
        area = cv.contourArea(contour)
        if area < 50000:
            continue
        if image_size * 0.99 < area:
            continue
        if abs(i - xxx) < 10:
            continue
        xxx = i
        x, y, w, h = cv.boundingRect(contour)
        cut = src[y:y+h, x:x+w]
        detector = cv.FastFeatureDetector_create()
        detector.setNonmaxSuppression(False)
        keypoints = detector.detect(cut)
        cv.imwrite('debug_%d.png' % i, cut)

if __name__ == '__main__':
    main()
将cv2作为cv导入
def main():
image_file='/path/to/your/input/image.png'
src=cv.imread(图像文件,cv.imread\u颜色)
高度、宽度、通道=src.shape
图像大小=高度*宽度
img_gray=cv.CVT颜色(src、cv.COLOR_RGB2GRAY)
retval,dst=cv.阈值(图像灰度,1000255,cv.阈值至零)
dst=cv.按位_非(dst)
retval,dst=cv.阈值(dst,0,255,cv.THRESH_BINARY | cv.THRESH_OTSU)
dst、等高线、层次=cv.findContours(
dst、cv.RETR_树、cv.CHAIN_近似值(简单)
xxx=0
对于i,枚举中的等高线(等高线):
面积=等高线等高线面积(等高线)
如果面积小于50000:
持续
如果图像大小*0.99<面积:
持续
如果abs(i-xxx)<10:
持续
xxx=i
x、 y,w,h=等高线边界矩形(等高线)
切割=src[y:y+h,x:x+w]
检测器=cv.FastFeatureDetector_create()
检测器。设置非最大值抑制(假)
关键点=检测器。检测(切割)
cv.imwrite('debug_u%d.png'%i,cut)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
请参阅本网站:


更新2

fmw42的方法很好,但它不足以满足我的以下要求。(我在第一篇文章中没有提到)只提取了蓝色矩形。背景色可能是白色

  • 输入图像(input2.png)

  • 实际结果图像(output.png)

尝试在图片上找到轮廓,并将其抓取到列表中:

import cv2
import imutils

path = r'/path/to/your/input/image.jpg'
image = cv2.imread(path)
cv2.imshow("input", image)

contours = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
grabbed_objects = imutils.grab_contours(contours)

通过进一步处理对象列表,可以获得所需的元素。可能通过按大小或其他方式过滤列表元素。

这可以在ImageMagick(6)中使用连接的组件完成

这里我转换到HSV颜色空间并提取饱和度通道。白色和黑色没有饱和度,但粉红色和蓝色有饱和度。然后设置阈值,使粉红色和蓝色在黑色背景上变为白色。然后我使用形态学腐蚀来消除边界的影响。然后,我使用连接的组件填充白色区域中的任何孔,然后获取它们的边界框并存储在阵列中。然后我在每个边界框上循环并裁剪原始图像

输入:

Unix语法:

bboxArr=(`convert wikipedia.png \
-colorspace HSV -channel 1 -separate +channel \
-threshold 0 -type bilevel \
-morphology erode square:3 \
-define connected-components:verbose=true \
-define connected-components:mean-color=true \
-define connected-components:area-threshold=1000 \
-connected-components 4 null: | grep "gray(255)" | awk '{print $2}'`)

num=${#bboxArr[*]}

for ((i=0; i<num; i++)); do
convert wikipedia.png -crop ${bboxArr[$i]} +repage wikipedia_$i.png
done
bboxArr=(`convert wikipedia.png\
-色彩空间HSV-通道1-独立+通道\
-阈值0型二层\
-形态侵蚀方格:3\
-定义连接的组件:verbose=true\
-定义连接的组件:平均颜色=真\
-定义连接的组件:面积阈值=1000\
-连接组件4 null:| grep“gray(255)”| awk'{print$2}`)
num=${bboxArr[*]}

为了((i=0;i共享您的代码可以帮助我们发现问题。这似乎是一个关于高度-宽度的问题。@YunusTemurlenk嗨。我不知道怎么做,所以无法显示代码。kalzso给了我一个想法,所以我稍后会向您显示一些代码。它工作得很好。但请给我更多的时间。正如您提到的,我已经确认我如果后端为白色,则t不起作用。该颜色在我的要求中也是可能的(是的,我在问题中没有提到。对不起..)。我现在正试图找到解决方案。是否需要所有文本段落?如果需要,则需要稍微不同的方法。首先,将所有文本设置为白色背景上的黑色。然后模糊文本或打开词法以连接每个段落中的文本。阈值。然后使用连接的组件查找文本区域边界框。然后使用边界框裁剪输入。嗨。不,我不需要文本段落。我需要提取output1.png和output2.png。我在问题中添加了细节。(更新2)