opencv replaces solid background with transparent background

Keywords: OpenCV

Recently, in the development of matting project, a colleague wants to remove a color. It's very easy to use OpenCV. I use opencv3, which has foreach to use

The pictures to be cut are as follows:

He wants to remove the black (0,0,0) background, so the code is as follows:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
const int color_drop = 0;
struct ForEachOperator {
	void operator ()(cv::Vec4b &pixel, const int *position) const {
		if (pixel[0] == color_drop && pixel[1] == color_drop && pixel[2] == color_drop)
			pixel[3] = 0;
	}
};

int main() {
	string path_src("/Users/jijun/Downloads/xi.png");
	string path_dest("/Users/jijun/Downloads/xi_alpha.png");

	Mat mat = cv::imread(path_src);
	Mat input_bgra;
	cvtColor(mat, input_bgra, CV_BGR2BGRA);

	input_bgra.forEach<Vec4b>(ForEachOperator());

	imwrite(path_dest, input_bgra);
	//release
	mat.release();
	input_bgra.release();
}


//#Compile run
​g++ opencv_test.cpp  `pkg-config --cflags --libs opencv`
./a.out

As shown in the figure, there are still many black values,

Use the color picker to grab the original image and find that what you see with the naked eye is not pure black, but in a range, so modify the source code:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
typedef unsigned int uint;
//Threshold positioning 20, also freely defined
const int color_drop = 20;
struct ForEachOperator {
	void operator ()(cv::Vec4b &pixel, const int *position) const {
		if (pixel[0] <= color_drop && pixel[1] <= color_drop && pixel[2] <= color_drop)
			pixel[3] = 0;
	}
};

int main() {
	string path_src("/Users/jijun/Downloads/xi.png");
	string path_dest("/Users/jijun/Downloads/xi_alpha.png");

	Mat mat = cv::imread(path_src);
	Mat input_bgra;
	cvtColor(mat, input_bgra, CV_BGR2BGRA);

	input_bgra.forEach<Vec4b>(ForEachOperator());

	imwrite(path_dest, input_bgra);
	//release
	mat.release();
	input_bgra.release();
}

Run again, the effect is as follows:

Posted by pod2oo5 on Sat, 04 Jan 2020 22:58:11 -0800