You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测与背景颜色高度相似的图像目标并实现黑白分割

问题描述

我有一张目标与背景颜色高度相似的图像,希望检测出该目标并将其设为白色,背景设为黑色。
![目标与背景高度相似的图像]

已尝试方案
  • 转为灰度图后用cv2.equalizeHist进行直方图均衡化
  • 用cv2.Canny检测边缘
  • 尝试调整HSV通道,但缺乏相关经验不确定效果及操作方式

其中CLAHE能略微提升目标可见度,实现代码如下:

import cv2
import tkinter.filedialog as fd

def main():
    filepath = fd.askopenfilename()
    image = cv2.imread(filepath)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    clahe = cv2.createCLAHE(clipLimit=5)
    cla = clahe.apply(gray)
    cv2.imshow("Image", cla)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

main()

但不确定后续该如何处理以完成目标检测,寻求解决方案。

编辑补充

@Christoph Rackwitz的方案效果很好,我也找到一种基于图像处理的方法,代码如下:

import cv2
import numpy as np
import tkinter.filedialog as fd

def bilateral_filter(image):
    return cv2.bilateralFilter(image, 30, 75, 175)

def enhance_image(image, h_luminance, photo_render, block_size, search_window, gamma):
    denoised_image = cv2.fastNlMeansDenoisingColored(image, None, h_luminance, photo_render, block_size, search_window)
    contrast_stretched_image = cv2.normalize(denoised_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8UC1)
    kernel = np.array([[0, -1, 0], [-1, 5, -1], [0, -1, 0]], np.float32)
    sharpened_image = cv2.filter2D(contrast_stretched_image, -1, kernel=kernel)
    improved_exposure = cv2.convertScaleAbs(sharpened_image, alpha=1, beta=5)
    lookup_table = np.array([((i / 255.0) ** gamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
    gamma_corrected_image = cv2.LUT(improved_exposure, lookup_table)
    return gamma_corrected_image

def convert_to_grayscale(image):
    return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

def black_and_white(image):
    return cv2.threshold(image, 0, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1]

def dilation(image, iter, ksize):
    kernel = np.ones((ksize, ksize), np.uint8)
    return cv2.dilate(image, kernel, iterations=iter)

def erosion(image, iter, ksize):
    kernel = np.ones((ksize, ksize), np.uint8)
    return cv2.erode(image, kernel, iterations=iter)

def closing(image, ksize):
    kernel = np.ones((ksize, ksize), np.uint8)
    return cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)

def sobel_filter(image):
    ddepth = cv2.CV_64F 
    ksize = cv2.FILTER_SCHARR 
    x = cv2.Sobel(image, ddepth, 1, 0, ksize=ksize, scale=1)
    y = cv2.Sobel(image, ddepth, 0, 1, ksize=ksize, scale=1)
    absx = cv2.convertScaleAbs(x)
    absy = cv2.convertScaleAbs(y)
    sobel_image = cv2.addWeighted(absx, 0.5, absy, 0.5, 0)
    return sobel_image

def use_clahe(grayscale_image, cliplimit):
    clahe = cv2.createCLAHE(clipLimit=cliplimit)
    cla = clahe.apply(grayscale_image)
    return cla

def process_image(image):
    contour_image = image.copy()
    sobel_image = sobel_filter(image)
    bilateral_image = bilateral_filter(sobel_image)
    h_luminance, photo_render, block_size, search_window, gamma = 7, 10, 6, 55, 5
    enhanced_image = enhance_image(bilateral_image, h_luminance, photo_render, block_size, search_window, gamma)
    grayscale_image = convert_to_grayscale(enhanced_image)
    clahe_process = use_clahe(grayscale_image, 20)
    thres = black_and_white(clahe_process)
    closed = closing(thres, 20)
    dilated = dilation(closed, 2, 2)
    eroded = erosion(dilated, 1, 4)
    processed_image = dilation(eroded, 2, 6)
    contours, _ = cv2.findContours(processed_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    for contour in contours:
        cv2.drawContours(contour_image, [contour], -1, [0, 0, 255], 2)
    return processed_image, contour_image

def show_image(texts, images):
    for i, image in enumerate(images):
        cv2.imshow("{}".format(texts[i]), image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def main():
    filepath = fd.askopenfilename()
    image = cv2.imread(filepath)
    processed_image, contour_image = process_image(image)
    texts = ["Image 1: Original", "Image 2: Processed", "Image 3: Contours"]
    images = [image, processed_image, contour_image]
    show_image(texts, images)
    quit()

main()

该方法通过滤波器和CLAHE增强图像,再对黑白图进行形态学操作,但效果并不完美,轮廓存在偏移。目前我正尝试优化该代码并研究@Christoph Rackwitz的方案,后续会更新进展。


内容的提问来源于stack exchange,提问作者programer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:45:59