查找并填充具有不同颜色的图像的轮廓

发布于 2025-01-25 13:56:53 字数 3034 浏览 5 评论 0 原文

我看到了这个答案:但就我而言,由于图像的亮度变化,我很难知道不同的颜色阈值,

所以我尝试分割植物的植物图像很少。有些植物的形状和颜色良好,但有些植物对叶子有褐色的色彩。我应该如何使用OpenCV对这些图像进行良好的分割。我首先想到使用检测,尽管我确实得到了边缘,但我无法填补空白,因此我使用了轮廓检测,但是它们的效果不佳,许多不太井层的植物具有颜色的变化。

我目前的方法试图在HSV Colorspace中找到绿色。它更容易定义绿色的色彩空间,但不是棕色的色彩。

import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, glob  

def method_1(img):
    # Blur the image
    blur = cv2.GaussianBlur(img,(9,9),cv2.BORDER_DEFAULT)
    ## convert to hsv
    hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)


    ## mask of green (36,25,25) ~ (86, 255,255)
    mask = cv2.inRange(hsv, (36, 25, 25), (85, 255,255))

    ## slice the green
    imask = mask>0
    green = np.zeros_like(img, np.uint8)
    green[imask] = img[imask]


    # apply dilation on src image
    kernel = np.ones((7,7),np.uint8)
    dilated_img = cv2.dilate(green, kernel, iterations = 2)


    # Draw contours and fill holes
    canvas = dilated_img.copy() # Canvas for plotting contours on
    canvas = cv2.cvtColor(canvas, cv2.COLOR_BGR2GRAY)
    contours, hierarchy = cv2.findContours(canvas, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)

    return canvas, contours


def get_mask(maskfolder, file_path, filename, savefile):
    contour_list = []

    img = cv2.imread(file_path)
    rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    
    plt.imshow(rgb_img)
    plt.show()

它适用于看起来像:

”“在此处输入图像说明”

但对于这样的图像:

此处输入图像说明”>

然后我使用了一个简单的轮廓方法

def method_2(img):
    blur = cv2.GaussianBlur(img, (5, 5), 0)
    gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
    contours, _ = cv2.findContours(gray,  cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

    return gray, contours

def get_mask(maskfolder, file_path, filename, savefile):
    contour_list = []

    img = cv2.imread(file_path)
    rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    # METHOD 2
    canvas_2, contours_2 = method_2(rgb_img)
    for cnt in contours_2:
        cv2.drawContours(canvas_2,[cnt],-1,255,-1)

    
    plt.imshow(canvas_2, cmap="gray")
    plt.show()

,但它返回黑色图像:

“在此处输入图像说明”

I saw this answer: Python - Finding contours of different colors on an image but in my case, it's becoming difficult to know different color thresholds because of varying brightness in images

I have few plant images where I am trying to segment the plant. Some plants have good shape and color but some have brownish tint to the leaves. How should I make a good segmentation of these images using opencv. I first thought of using detection and though I did get edges, I couldn't fill the gaps so I used contour detection and but they don't work well many many not-so-well-shaped plants with variation in color.

My current method attempts to find green color in HSV colorspace.It's easier to define green colorspace but not for the little brownish tints.

import cv2
import matplotlib.pyplot as plt
import numpy as np
import os, glob  

def method_1(img):
    # Blur the image
    blur = cv2.GaussianBlur(img,(9,9),cv2.BORDER_DEFAULT)
    ## convert to hsv
    hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)


    ## mask of green (36,25,25) ~ (86, 255,255)
    mask = cv2.inRange(hsv, (36, 25, 25), (85, 255,255))

    ## slice the green
    imask = mask>0
    green = np.zeros_like(img, np.uint8)
    green[imask] = img[imask]


    # apply dilation on src image
    kernel = np.ones((7,7),np.uint8)
    dilated_img = cv2.dilate(green, kernel, iterations = 2)


    # Draw contours and fill holes
    canvas = dilated_img.copy() # Canvas for plotting contours on
    canvas = cv2.cvtColor(canvas, cv2.COLOR_BGR2GRAY)
    contours, hierarchy = cv2.findContours(canvas, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)

    return canvas, contours


def get_mask(maskfolder, file_path, filename, savefile):
    contour_list = []

    img = cv2.imread(file_path)
    rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    
    plt.imshow(rgb_img)
    plt.show()

It works fine for images which look like:

enter image description here

but not for images like this:

enter image description here

Sample results below

enter image description here
enter image description here

I then used a simple contouring method

def method_2(img):
    blur = cv2.GaussianBlur(img, (5, 5), 0)
    gray = cv2.cvtColor(blur, cv2.COLOR_BGR2GRAY)
    contours, _ = cv2.findContours(gray,  cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)

    return gray, contours

def get_mask(maskfolder, file_path, filename, savefile):
    contour_list = []

    img = cv2.imread(file_path)
    rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)

    # METHOD 2
    canvas_2, contours_2 = method_2(rgb_img)
    for cnt in contours_2:
        cv2.drawContours(canvas_2,[cnt],-1,255,-1)

    
    plt.imshow(canvas_2, cmap="gray")
    plt.show()

but it returns black images:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

长梦不多时 2025-02-01 13:56:53

您可以通过标准化颜色来摆脱变化的照明(将RGB组件划分为总和)。无论如何,饱和区域永远丢失。

您可以根据您选择的几种颜色,通过最近的邻居规则对背景与前景进行分类。如果您需要自动解决方案,则可以开始使用K-Nearest Quniger算法。

”在此处输入图像说明”

You can get rid of varying illumintation by normalizing the colors (divide the RGB components by their sum). Anyway, the saturated areas are forever lost.

The you can classify the background vs. the foreground by the nearest neighbor rule, based on a few colors that you pick. If you need an automated solution, the k-nearest neighbor algorithm can be a start.

enter image description here

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文