简体   繁体   English

在 python 中取 OpenCV 的最大连接分量

[英]Taking the largest component of connected components with OpenCV in python

I have some photos of leaves with alpha channel - the background alpha channel is 0, and the leaf pixels alpha channel in the photo is 255.我有一些带有 alpha 通道的叶子照片 - 背景 alpha 通道为 0,照片中的叶子像素 alpha 通道为 255。

I want to separate the image to connected Components.我想将图像分离为连接的组件。 and then take the large connected Component.然后取大连接组件。 in order to erase dirt like in the red mark.为了像红色标记一样擦除污垢。 This is the image I'm talking about here: leaf image这是我在这里谈论的图像:叶子图像

And this is my current code:这是我当前的代码:

def remove_pixels(image_path, img_file_output_path):
    img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
    alpha = img[:, :, 3]
    alpha = cv2.threshold(alpha, 0, 255, cv2.THRESH_BINARY)[1]
    num_labels, labels_im = cv2.connectedComponents(alpha,connectivity=4)
    new_img = np.zeros(img.shape)
    largest_label = 1 + np.argmax(labels_im[1:, cv2.CC_STAT_AREA])  
    h, w = labels_im.shape
    for i in range(h*w):
        x = i // w
        y = i % w
        if labels_im[x,y] == largest_label:
            new_img[x,y] = img[x,y]
    cv2.imwrite(img_file_output_path, new_img)

It is not working, any help is really appreciated.它不起作用,非常感谢任何帮助。
Thank you:)谢谢:)
------------------------------------------------- -------------------------------------------------

This is my new code:这是我的新代码:

def remove_pixels(image_path, img_file_output_path):
    img = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
    alpha = img[:, :, 3]
    contours = cv2.findContours(alpha, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    big_contour = max(contours, key=cv2.contourArea)

    # draw white filled contour on black background to use as new alpha channel
    new_alpha = np.zeros_like(alpha)
    new_alpha = cv2.drawContours(new_alpha, [big_contour], 0, 255, -1)

    # put new_alpha into alpha channel of img
    new_img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
    new_img[:, :, 3] = new_alpha

    cv2.imwrite(img_file_output_path, new_img)

and the picture: new picture和图片:新图片

Here is one way in Python/OpenCV.这是 Python/OpenCV 中的一种方法。

 - Read the input
 - Threshold on white and invert so that the leaf, etc is white on black background
 - Get the contours
 - Filter the contours on area to keep only the largest
 - Draw a white filled contour on a black background using the largest contour
 - Put that image into the alpha channel of the input
 - Save the result

Input:输入:

在此处输入图像描述

import cv2
import numpy as np

# load image
img = cv2.imread('leaf3.jpg')

# threshold on white and invert
thresh = cv2.inRange(img, (220,220,220), (255,255,255))
thresh = 255 - thresh

# get the largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# draw white filled contour on black background to use as new alpha channel
new_alpha = np.zeros_like(thresh)
new_alpha = cv2.drawContours(new_alpha, [big_contour], 0, 255, -1)

# put new_alpha into alpha channel of img 
new_img = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
new_img[:, :, 3] = new_alpha

# save result
cv2.imwrite("leaf3_alpha_cleaned.png", new_img)

Result:结果:

在此处输入图像描述

Optional - Make the background white in place of transparent.可选 - 将背景设置为白色而不是透明。

# make background white
new_img2 = img.copy()
new_img2[new_alpha==0] = (255,255,255)
cv2.imwrite("leaf3_alpha_cleaned2.png", new_img2)

在此处输入图像描述

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

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