[英]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.