How to make the white part of an image transparent using Android opencv

I can’t link URLs over 2 to post my photos on this blog. see my problems here. http://blog.naver.com/mail1001/220650041897

I want to know how to make the white part of the image, which is white paper with a recording on it, transparent using Android opencv.

I studied the URL (I wrote it on a blog), which makes the black background transparent, and I think the Alpha Channel has something to do with it.

I think this will work when I make the Alpha Channel, by making the part that I want to make transparent black and the other part white, and combine this alpha channel with the original RGB channel.

So, I did two experiments.

1) I made the part of the papier black and the white part of the letter to make the alpha channel. And combined it with the RGB channel.

(Please see the blog. Experiment 1 alpha channel image)

I thought that the record should be the same, and the background should be transparent, but the background only turned into white and a bit transparent.

(Please see the blog. Experiment Result 1)

2) This time, the paper part is white, and the recording part is black. But this time only the recording turned into transparent.

(Please see the blog. Experiment 2 alpha channel image and result image)

In the second experiment, I wanted to make transparent transparent, but in the first experiment this did not work.

What part am I doing wrong? Is there some kind of concept that I misunderstand?

This is the source I tested.

Bitmap test(Bitmap image) { // convert image to matrix Mat src = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4); Utils.bitmapToMat(image, src); // init new matrices Mat dst = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4); Mat tmp = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4); Mat alpha = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4); // convert image to grayscale Imgproc.cvtColor(src, tmp, Imgproc.COLOR_BGR2GRAY); // threshold the image to create alpha channel with complete transparency in black background region and zero transparency in foreground object region. Imgproc.threshold(tmp, alpha, 100, 255, Imgproc.THRESH_BINARY_INV); //Imgproc.threshold(tmp, alpha, 100, 255, Imgproc.THRESH_BINARY); // split the original image into three single channel. List<Mat> rgb = new ArrayList<Mat>(3); Core.split(src, rgb); // Create the final result by merging three single channel and alpha(BGRA order) List<Mat> rgba = new ArrayList<Mat>(4); rgba.add(rgb.get(0)); rgba.add(rgb.get(1)); rgba.add(rgb.get(2)); rgba.add(alpha); Core.merge(rgba, dst); // convert matrix to output bitmap Bitmap output = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888); Utils.matToBitmap(dst, output); //Utils.matToBitmap(alpha, output); return output; } 

Thank you for your good reply.

I tried, but it was the same experimental result. T_T

Change code

 Bitmap makeBackgroundWhite(Bitmap image) { // convert image to matrix Mat src = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4); Utils.bitmapToMat(image, src); // init new matrices Mat dst = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4); Mat tmp = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8U); Mat alpha = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8U); // convert image to grayscale Imgproc.cvtColor(src, tmp, Imgproc.COLOR_BGR2GRAY); // threshold the image to create alpha channel with complete transparency in black background region and zero transparency in foreground object region. Imgproc.threshold(tmp, alpha, 100, 255, Imgproc.THRESH_BINARY_INV); // split the original image into three single channel. List<Mat> bgra = new ArrayList<Mat>(4); Core.split(src, bgra); // Create the final result by merging three single channel and alpha(BGRA order) bgra.remove(3); bgra.add(alpha); Core.merge(bgra, dst); // convert matrix to output bitmap Bitmap output = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888); Utils.matToBitmap(dst, output); return output; } 
+3
source share
1 answer

There are several problems in your code.
I think both cases went wrong, but the second case was just lucky to pretend to be successful.
The reason the second case works well is because the fonts are mostly black.
Look closely at the heart (red) image, and you may find that the second case also failed.
(Perhaps you are out of luck, if both cases failed, you will immediately notice the problem :))

1.You use tmp (gray) and alpha mat with CV_8UC4.
gray and alpha only require 1 byte per pixel, so change them to CV_8U.

 Mat tmp = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8U); Mat alpha = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8U); 


2. Types of color confuse
src Mat and tmp Mat are initialized by CV_8UC4, and you convert src to tmp with the conversion code: COLOR_BGR2GRAY.
OpenCV converts the matrix even if the actual color type does not match the conversion code, so you MUST synchronize them to make sense.

 // suppose you've already changed the type of tmp to CV_8U Imgproc.cvtColor(src, tmp, Imgproc.COLOR_BGRA2GRAY); 


3.Splitting and Merging
your src is 4 channel and you split it into 3.
I don’t know how OpenCV works in this situation, but I highly recommend that you map channels.

 ArrayList<Mat> bgra = new ArrayList<Mat>(4); Core.split(src, bgra); bgra.remove(3); bgra.add(alpha); // suppose your alpha channel is already CV_8U Core.merge(bgra, dst); 



ADDED: C ++ version source code
Hope this helps.

 // 1. Loading Mat src = imread("yourImagePath/yourOriginalImage.jpg"); // This code will automatically loads image to Mat with 3-channel(BGR) format // 2. Grayscaling Mat gray; cvtColor(src, gray, CV_BGR2GRAY); // This will convert BGR src to GRAY // 3. Thresholding Mat mask; threshold(gray, mask, 100, 255, CV_THRES_BINARY); // Or use CV_THRES_BINARY_INV for inverting result // 4. Splitting & adding Alpha vector<Mat> channels; // C++ version of ArrayList<Mat> split(src, channels); // Automatically splits channels and adds them to channels. The size of channels = 3 channels.push_back(mask); // Adds mask(alpha) channel. The size of channels = 4 // 5. Merging Mat dst; merge(channels, dst); // dst is created with 4-channel(BGRA). // Note that OpenCV applies BGRA by default if your array size is 4, // even if actual order is different. In this case this makes sense. // 6. Saving imwrite("yourImagePath/yourDstImage.png", dst); // Used PNG format for preserving ALPHA channel 
+1
source

Source: https://habr.com/ru/post/1259545/


All Articles