繁体   English   中英

删除图像中的小背景(黑色)区域

[英]Remove small background (black) regions within an image

附件为图像。 我能够摆脱边界上的背景区域,但是图像内的背景区域仍然持久。 是否有任何方法可以消除图像中的小背景区域。 谢谢。 在此处输入图片说明

有一个解决此问题的简单方法,其基本思想是在RGB颜色空间中分割图像,以滤除图像中残留的黑色部分,可以将其简单实现为:

import cv2
import numpy as np 

ornament_image = cv2.imread("/Users/anmoluppal/Desktop/outputs/ornament.jpg")

#Considering the black range of background pixels
thresh = cv2.inRange(ornament_image, np.array([0, 0, 0]), np.array([55, 55, 55]))

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

cv2.drawContours(ornament_image, contours, -1, (255,255,255), -1)
#Replace the contours with the white color same as the background

在此处输入图片说明

但这会去除装饰图像中的一些非常小的黑色部分,为了保留这些部分,我们可以根据轮廓区域对它们进行分类,从而过滤掉某些轮廓,如下所示:

thresh = cv2.inRange(ornament_image, np.array([0, 0, 0]), np.array([55, 55, 55]))

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

contours = sorted(contours, key = cv2.contourArea, reverse = True)[:len(contours)/20]

cv2.drawContours(ornament_image, contours, -1, (255,255,255), -1)

注意:此方法也可以保留一些黑色背景噪音

在此处输入图片说明

进一步改进:

  • YCrCb分割 :如果您对RGB分割不满意,则也可以尝试对给定图像进行YCrCb分割,这通常在数字图像中使用。

  • 遮罩 :您可能还注意到了,装饰品绿色宝石内部的黑色由于其内部的黑色斑点也已与背景融合,可以通过创建遮罩来消除该遮罩,该遮罩会阻止给定ROI中的任何分割,因此保留了必要的细节,但这需要人工干预。

以上代码在c ++和手动掩码中添加。

#include <iostream>
#include "opencv2/opencv.hpp"
#include <stdio.h>

using namespace std;
using namespace cv;

Mat thresh, hierarchy;

void onMouse( int event, int x, int y, int flags, void* imgptr ){
    if ( flags == (EVENT_FLAG_CTRLKEY + EVENT_FLAG_LBUTTON) ) //Sure Background - Red
        {

       Mat & img = (*(Mat*)imgptr); // first cast, then deref
       Point pt1 = Point(x, y);
       circle(img, pt1, 7, Scalar(0,0,255), -1, 8);
       imshow("Mark Image", img);
       waitKey(1);
        }
}

int main ()
{
    int i =0;

    Mat src = imread("C:/Users/Dell/Desktop/computervisionproject/segmentation/segmentation/Final_window.jpg",1);
    Mat image = src.clone();

    namedWindow("Mark Image",WINDOW_NORMAL);
    setMouseCallback("Mark Image",onMouse, &image);
    imshow("Mark Image",image);

    while(1){
    char c=waitKey();
    if(c=='s'){
    inRange(image, cv::Scalar(0, 0, 0), cv::Scalar(55, 55, 55), thresh);

    std::vector<std::vector<cv::Point> > contours;
    findContours(thresh,contours, hierarchy, CV_RETR_TREE ,CV_CHAIN_APPROX_NONE);
    //findContours(thresh,contours, CV_RETR_TREE ,CV_CHAIN_APPROX_NONE);
    cout <<"Hello"<<endl;


    drawContours(src, contours, -1, Scalar(255,255,255), -1);

    namedWindow( "Display window", WINDOW_NORMAL );
    imshow( "Display window", src);
    }
    }

    waitKey();
    return 0;
}

暂无
暂无

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

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