Java 如何将材质对象设置为颜色模式?[OpenCV]
我正在做一个关于使用分水岭算法进行图像分割的教程,我想知道在将图像分割成前景和背景后是否得到了正确的结果 要求使用imageView将最终目标对象的前景恢复到彩色模式。我用“一片叶子”的照片作为例子,我想看到绿色的背,让我自己高兴,我正在把物体从背景中拿出来 这是我的代码(请随意评论我做错了什么,或者我提出了一个更好的解决方案。我是android开发和OpenCV的新手): 以下是我的标记代码:Java 如何将材质对象设置为颜色模式?[OpenCV],java,android,opencv,image-segmentation,watershed,Java,Android,Opencv,Image Segmentation,Watershed,我正在做一个关于使用分水岭算法进行图像分割的教程,我想知道在将图像分割成前景和背景后是否得到了正确的结果 要求使用imageView将最终目标对象的前景恢复到彩色模式。我用“一片叶子”的照片作为例子,我想看到绿色的背,让我自己高兴,我正在把物体从背景中拿出来 这是我的代码(请随意评论我做错了什么,或者我提出了一个更好的解决方案。我是android开发和OpenCV的新手): 以下是我的标记代码: //Markers image: Mat markersMat = new Mat(
//Markers image:
Mat markersMat = new Mat(grayscaleMat.size(), CvType.CV_8U, new Scalar(0));
Core.add(foregroundMat, backgroundMat, markersMat);
//show markers:
Bitmap markersBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(markersMat, markersBmp);
imgView_markers.setImageBitmap(markersBmp);
同样,我的问题是如何在颜色模式下设置finalMat(返回叶子的颜色)
以下是我的活动完整代码:
//Set Original pic:
String originalFilePathStr= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) +"/healthy1.jpg";
Mat originalPicMat = Imgcodecs.imread(originalFilePathStr);
//set imageview:
//File originalPicFilePath = new File(originalFilePathStr+"/healthy.jpg");
Uri originalPicUriPath = Uri.parse(originalFilePathStr);
imgView_original.setImageURI(originalPicUriPath);
/* IMAGE SEGMENTATION USING WATERSHED ALGORITHM */
//Create a Mat Object using originalPicture as is:
/* OTSU'S BINARIZATION */
Mat grayscaleMat = new Mat();
//check if i dont need to load_image as grayscale, if cvtColor does does work or vice versa:
Imgproc.cvtColor(originalPicMat, grayscaleMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(grayscaleMat, grayscaleMat, 0, 255, Imgproc.THRESH_BINARY_INV + Imgproc.THRESH_OTSU);
//test grayscale: WORKS:
Bitmap grayscaleBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(grayscaleMat, grayscaleBmp);
imgView_grayscale.setImageBitmap(grayscaleBmp);
//Part 2: Create marker: foregroun dnd background
//Sure fg area:
Mat foregroundMat = new Mat();
Imgproc.erode(grayscaleMat, foregroundMat, new Mat(),new Point(-1,-1),2);
//Show fg area:
Bitmap foregroundBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(grayscaleMat, foregroundBmp);
imgView_foreground.setImageBitmap(foregroundBmp);
//Mat Bg:
Mat backgroundMat = new Mat();
Imgproc.dilate(grayscaleMat, backgroundMat, new Mat(), new Point(-1,-1), 3);
Imgproc.threshold(backgroundMat, backgroundMat, 1,128, Imgproc.THRESH_BINARY_INV);
Bitmap backgroundBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(backgroundMat, backgroundBmp);
imgView_background.setImageBitmap(backgroundBmp);
//Markers image:
Mat markersMat = new Mat(grayscaleMat.size(), CvType.CV_8U, new Scalar(0));
Core.add(foregroundMat, backgroundMat, markersMat);
//show markers:
Bitmap markersBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(markersMat, markersBmp);
imgView_markers.setImageBitmap(markersBmp);
/*Watershed: Finale */
//test watershed:
Mat finalMat = markersMat;
finalMat.convertTo(markersMat, CvType.CV_32S);
Imgproc.watershed(originalPicMat, finalMat);
//then return as CV_8U:
finalMat.convertTo(finalMat, CvType.CV_8U);
//test at final output:
Bitmap testBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(finalMat, testBmp);
imgView_finalOutput.setImageBitmap(testBmp);
是我活动结果的截图(没有足够的声誉点数发布截图)
更新:
它现在工作了,我现在可以标记叶子了。我现在唯一的问题是它返回不同颜色的叶子。请参考照片
最后一张照片返回不同的绿色阴影,黄色变为蓝色。问题是我不知道bug是从哪里来的。如果你们知道问题出在哪里,请告诉我。有一个名为copyTo的函数,可以接受掩码(二进制图像),只需将原始图像复制到带有掩码的新垫子上,就可以分割彩色图像。在遮罩中,将复制白色值,而不会复制黑色值。我认为你的前景图像可以像maskAgain一样工作,你可以只使用颜色矩阵来制作一个二值(正色)图像,而不必麻烦外部库。又是你们!我真的很感谢你的快速回复。我试着模仿,效果很好。我现在唯一的问题是叶子的颜色和原来的图片不一样。如果你们知道我的问题来自哪里,请分享。我会非常感激的@api55@ModularSynth:是的,兄弟,我真的很想试试。在尝试不同的方法之前,我尝试先按照说明进行操作。但我会试试你的,因为它是灰度图像更好的解决方案。我真的很感激。@Jepoy问题可能是opencv是BGR,可能在某个地方你把它当作RGB,所以颜色通道的顺序不正确。。。。或者至少我认为这可能是问题所在有一个名为copyTo的函数,它可以接受一个掩码(二进制图像),只要用掩码将原始图像复制到一个新的垫子上,就可以对彩色图像进行分割。在遮罩中,将复制白色值,而不会复制黑色值。我认为你的前景图像可以像maskAgain一样工作,你可以只使用颜色矩阵来制作一个二值(正色)图像,而不必麻烦外部库。又是你们!我真的很感谢你的快速回复。我试着模仿,效果很好。我现在唯一的问题是叶子的颜色和原来的图片不一样。如果你们知道我的问题来自哪里,请分享。我会非常感激的@api55@ModularSynth:是的,兄弟,我真的很想试试。在尝试不同的方法之前,我尝试先按照说明进行操作。但我会试试你的,因为它是灰度图像更好的解决方案。我真的很感激。@Jepoy问题可能是opencv是BGR,可能在某个地方你把它当作RGB,所以颜色通道的顺序不正确。。。。或者至少我认为这可能是问题所在
//Set Original pic:
String originalFilePathStr= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) +"/healthy1.jpg";
Mat originalPicMat = Imgcodecs.imread(originalFilePathStr);
//set imageview:
//File originalPicFilePath = new File(originalFilePathStr+"/healthy.jpg");
Uri originalPicUriPath = Uri.parse(originalFilePathStr);
imgView_original.setImageURI(originalPicUriPath);
/* IMAGE SEGMENTATION USING WATERSHED ALGORITHM */
//Create a Mat Object using originalPicture as is:
/* OTSU'S BINARIZATION */
Mat grayscaleMat = new Mat();
//check if i dont need to load_image as grayscale, if cvtColor does does work or vice versa:
Imgproc.cvtColor(originalPicMat, grayscaleMat, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(grayscaleMat, grayscaleMat, 0, 255, Imgproc.THRESH_BINARY_INV + Imgproc.THRESH_OTSU);
//test grayscale: WORKS:
Bitmap grayscaleBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(grayscaleMat, grayscaleBmp);
imgView_grayscale.setImageBitmap(grayscaleBmp);
//Part 2: Create marker: foregroun dnd background
//Sure fg area:
Mat foregroundMat = new Mat();
Imgproc.erode(grayscaleMat, foregroundMat, new Mat(),new Point(-1,-1),2);
//Show fg area:
Bitmap foregroundBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(grayscaleMat, foregroundBmp);
imgView_foreground.setImageBitmap(foregroundBmp);
//Mat Bg:
Mat backgroundMat = new Mat();
Imgproc.dilate(grayscaleMat, backgroundMat, new Mat(), new Point(-1,-1), 3);
Imgproc.threshold(backgroundMat, backgroundMat, 1,128, Imgproc.THRESH_BINARY_INV);
Bitmap backgroundBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(backgroundMat, backgroundBmp);
imgView_background.setImageBitmap(backgroundBmp);
//Markers image:
Mat markersMat = new Mat(grayscaleMat.size(), CvType.CV_8U, new Scalar(0));
Core.add(foregroundMat, backgroundMat, markersMat);
//show markers:
Bitmap markersBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(markersMat, markersBmp);
imgView_markers.setImageBitmap(markersBmp);
/*Watershed: Finale */
//test watershed:
Mat finalMat = markersMat;
finalMat.convertTo(markersMat, CvType.CV_32S);
Imgproc.watershed(originalPicMat, finalMat);
//then return as CV_8U:
finalMat.convertTo(finalMat, CvType.CV_8U);
//test at final output:
Bitmap testBmp = Bitmap.createBitmap(grayscaleMat.cols(), grayscaleMat.rows(),Bitmap.Config.ARGB_8888);
Utils.matToBitmap(finalMat, testBmp);
imgView_finalOutput.setImageBitmap(testBmp);