简体   繁体   中英

Mask image in opencv java

I need to convert near white pixels to white and near black pixels to black.

I found a code snippet in python on how to do it.

hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
# Define lower and upper limits of what we call "brown"
brown_lo=np.array([10,0,0])
brown_hi=np.array([20,255,255])
# Mask image to only select browns
mask=cv.inRange(hsv,brown_lo,brown_hi)
# Change image to red where we found brown
image[mask>0]=(0,0,255)

I have converted it java as below.

Mat temp= new Mat();
Imgproc.cvtColor(src,temp,COLOR_BGR2HSV);
Scalar low= new Scalar(10,0,0);
Scalar high= new Scalar(20,255,255);
Mat mask = new Mat();
inRange(temp,low,high,mask);

But I am facing problem converting below statement to java and there is no good opencv documentation in java with samples.

image[mask>0]=(0,0,255)

Could somebody help on how to convert above statement to java...?

I have tried setTo but it is not giving desired behaviour(attached screenshot below). Refer https://stackoverflow.com/a/50215020/12643143 for the expected result.

src.setTo(new Scalar(0,0,255),mask);

I recommend to use setTo() . This method can set all he pixels in a Mat . If an optionally mask argument is specified, then all the pixels who have a corresponding pixel with a non-zero value in the mask will be set.

Thus the python statement

image[mask>0]=(0,0,255)

can be substituted in Java by:

image.setTo(new Scalar(0, 0, 255), mask);

where image has to be a Mat object.

Answer to the question

As @Rabbid76 mentioned setTo is the correct way to do this. However if you want specific logic like image[mask>127]=(0,0,255) , then do threshold ( Imgproc.threshold(grey,grey, 127, 255, THRESH_BINARY); ) and then use setTo .

Solution to my problem

Actually my problem was not due to setTo . Its the logic mismatch between how I read/write the Mat in my code Vs the post I referred.

I am posting the solution to the problem that I have faced so that it might help new bees like me.

Problem in reading Image

The post use Imgcodecs.imread() to read image to Mat in BGR format.

Whereas I am loading bitmap using bitmapToMat in CV_8UC4 type as below which reads the image to Mat in RGBA format.

Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CV_8UC4);
org.opencv.android.Utils.bitmapToMat(bitmap, src);

Fix is to convert the format properly.

Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CV_8UC3); //notice 3 channel
org.opencv.android.Utils.bitmapToMat(bitmap, src);
Imgproc.cvtColor(src,hsv,COLOR_RGB2HSV); //Convert RGB to HSV. COLOR_RGBA2HSV not exist, hence we load it in CV_8UC3(3 channel R,G,B).

Problem in writing the Image

Similarly as we have differences in reading between bitmapToMat and imread , the same are applicable for writing. Imgcodecs.imwrite() will write the BGR image to bitmap, where as I have to convert it back to RGB format for matToBitmap to work like Imgproc.cvtColor(rgb, rgb, Imgproc.COLOR_BGR2RGB);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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