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

时间:2015-10-14 06:19:48

标签: c++ matlab opencv image-processing

附图是图像。我能够摆脱跨越边界的背景区域,但图像中的背景区域仍然是持久的。有没有任何方法可以摆脱图像中的小背景区域。谢谢。enter image description here

2 个答案:

答案 0 :(得分:4)

这个问题有一个简单的解决方法,基本思路是在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

enter image description here

但这会删除装饰图像中的一些非常小的黑色部分,为了保留这些部分,我们可以通过在轮廓区域的基础上对它们进行排序来过滤掉一些轮廓

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)

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

enter image description here

进一步改进:

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

  • 遮蔽:您可能已经注意到,由于黑色补丁,装饰品的 Green Gem 内的黑色也与背景合并在它内部,这可以通过创建一个掩盖来删除,这将阻碍给定ROI中的任何分段,因此保留了必要的细节,但这需要人为干预。

答案 1 :(得分:0)

添加了上面的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;
}