opencv java中的掩模图像

RAM*_*AMU 5 python java opencv numpy

我需要将接近白色的像素转换为白色,将接近黑色的像素转换为黑色。

我在 python 中找到了一个关于如何做到这一点的代码片段。

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)
Run Code Online (Sandbox Code Playgroud)

我已经将其转换为java,如下所示。

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);
Run Code Online (Sandbox Code Playgroud)

但是我在将下面的语句转换为java时遇到问题,并且java中没有好的opencv文档和示例。

image[mask>0]=(0,0,255)
Run Code Online (Sandbox Code Playgroud)

有人可以帮助如何将上面的语句转换为java...吗?

我尝试过 setTo 但它没有给出所需的行为(下面附有屏幕截图)。请参阅/sf/answers/3515051431/了解预期结果。

src.setTo(new Scalar(0,0,255),mask);
Run Code Online (Sandbox Code Playgroud)

RAM*_*AMU 1

回答问题

正如 @Rabbid76 提到的那样,setTo这是执行此操作的正确方法。但是,如果您想要特定的逻辑,例如image[mask>127]=(0,0,255),则执行threshold( Imgproc.threshold(grey,grey, 127, 255, THRESH_BINARY);),然后使用setTo

解决我的问题

实际上我的问题不是由于setTo. 这是我在代码中读/写 Mat 的方式与我提到的帖子之间的逻辑不匹配。

我将我遇到的问题的解决方案发布出来,以便它可以帮助像我这样的新蜜蜂。

读取图像时出现问题

该帖子用于Imgcodecs.imread()将 BGR 格式的图像读取到 Mat。

而我使用如下类型加载位图bitmapToMatCV_8UC4它将图像以 RGBA 格式读取到 Mat。

Mat src = new Mat(bitmap.getHeight(), bitmap.getWidth(), CV_8UC4);
org.opencv.android.Utils.bitmapToMat(bitmap, src);
Run Code Online (Sandbox Code Playgroud)

修复方法是正确转换格式。

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).
Run Code Online (Sandbox Code Playgroud)

写入图像时出现问题

类似地,正如我们在阅读bitmapToMat和阅读方面存在差异imread一样,这同样适用于写作。Imgcodecs.imwrite()会将 BGR 图像写入位图,因为我必须将其转换回 RGB 格式才能matToBitmap正常工作Imgproc.cvtColor(rgb, rgb, Imgproc.COLOR_BGR2RGB);