简体   繁体   English

opencv:如何合并近轮廓以获得最大的外轮廓?

[英]opencv: how to merge near contours to get the one big outest contour?

I am trying to digitize the kid's drawing into SVG or transparent png file format so that they can be used in Scratch.我正在尝试将孩子的绘图数字化为 SVG 或透明 png 文件格式,以便它们可以在 Scratch 中使用。 The white paper should be replaced by transparent background and all the drawing part should be preserved.应将白纸替换为透明背景,并保留所有绘图部分。

My plan is to get the outest contour of the drawing and generate a mask, then use the mask to get the drawing part without paper background.我的计划是获取图纸的最外轮廓并生成蒙版,然后使用蒙版获取没有纸张背景的绘图部分。

The problem is the drawing may not consecutive which means there may have some small holes leading to break the entire drawing contour to many many small contours.问题是绘图可能不连续,这意味着可能有一些小孔导致整个绘图轮廓中断为许多小轮廓。

Now I want to concatenate the near outest contours to form a big outest contour for masking.现在我想连接最近的外轮廓以形成一个大的外轮廓进行遮蔽。

The original drawing and the processed result is attached.附上原图及处理结果。

在此处输入图像描述

Code:代码:

from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
import random as rng
rng.seed(12345)
def thresh_callback(val):
    threshold = val
    # Detect edges using Canny
    canny_output = cv.Canny(src_gray, threshold, threshold * 2)
    # Find contours
    contours, hierarchy = cv.findContours(canny_output, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    # Draw contours
    drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
    for i in range(len(contours)):
        color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
        cv.drawContours(drawing, contours, i, color, 2, cv.LINE_8, hierarchy, 0)
    # Show in a window
    cv.imshow('Contours', drawing)
# Load source image
parser = argparse.ArgumentParser(description='Code for Finding contours in your image tutorial.')
parser.add_argument('--input', help='Path to input image.', default='IMG_4446.jpg')
args = parser.parse_args()
src = cv.imread(cv.samples.findFile(args.input))
if src is None:
    print('Could not open or find the image:', args.input)
    exit(0)
# Convert image to gray and blur it
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_gray = cv.blur(src_gray, (3,3))
# Create Window
source_window = 'Source'
cv.namedWindow(source_window)
cv.imshow(source_window, src)
max_thresh = 255
thresh = 100 # initial threshold
cv.createTrackbar('Canny Thresh:', source_window, thresh, max_thresh, thresh_callback)
thresh_callback(thresh)
cv.waitKey()
import cv2, numpy as np

# Read Image
img = cv2.imread('/home/stephen/Desktop/test_img.png')
img  =cv2.resize(img, (750,1000))

测试图片

# Find the gray image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # Gray
gray = cv2.blur(gray, (2,2))
cv2.imwrite('/home/stephen/Desktop/gray.png',gray)

灰色的

# Find the canny image
canny = cv2.Canny(gray, 30, 150) # Canny

# Find contours
contours, _ = cv2.findContours(canny,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

# Draw contours on canny (this connects the contours)
cv2.drawContours(canny, contours, -1, 255, 6)
cv2.imwrite('/home/stephen/Desktop/contours.png',canny)

轮廓

# Get mask for floodfill
h, w = canny.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)

面具

# Floodfill from point (0, 0)
cv2.floodFill(canny, mask, (0,0), 123)
cv2.imwrite('/home/stephen/Desktop/floodfill.png',canny)

洪水填充

# Exclude everying but the floodfill region
canny = cv2.inRange(canny, 122, 124)
cv2.imwrite('/home/stephen/Desktop/inrange.png',canny)

在范围内

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM