I am trying to convert some OpenCV Mat to grayscale for Contours detection algorithms. For some reason the image after convertion is all black. Mine code (b is Android Bitmap):
Mat tmp = new Mat (b.getWidth(), b.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(b, tmp);
Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_BGR2GRAY);
//there could be some processing
Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_GRAY2BGRA, 4);
Utils.matToBitmap(tmp, b);
And now I am drawing this bitmap and it is all black. When I applied contour detection to this bitmap (in place of comment) there were no match, so I assume problem is with convertion. After removing convertion (simply call bitmapToMat and matToBitmap) then bitmap is not all black so convertion to Mat are also working. Bitmap is in ARGB_8888 and there are no errors, just the output bitmap is all black.
Edit: Just to be sure I tried to save a bitmap with ocv imwrite - it's still all black so the problem is for 100% at cvtColor...
If the bitmap b is from the android device, then try using COLOR_RGB2GRAY instead of COLOR_BGR2GRAY because BGR is the default pixel format for OpenCV images, not all images.
Try this code:
Mat tmp = new Mat (b.getWidth(), b.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(b, tmp);
Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_RGB2GRAY);
//there could be some processing
Imgproc.cvtColor(tmp, tmp, Imgproc.COLOR_GRAY2RGB, 4);
Utils.matToBitmap(tmp, b);
I tried this method and it works perfectly, first you must convert it into grey scale, then to Canny, and finally to Bitmap.
this function returns a black and white image.
public static Bitmap edgesim(Mat img1) {
Bitmap image1;
//mat gray img1 holder
Mat imageGray1 = new Mat();
//mat canny image
Mat imageCny1 = new Mat();
//mat canny image
Mat imageCny2 = new Mat();
/////////////////////////////////////////////////////////////////
//Convert img1 into gray image
Imgproc.cvtColor(img1, imageGray1, Imgproc.COLOR_BGR2GRAY);
//Canny Edge Detection
Imgproc.Canny(imageGray1, imageCny1, 10, 100, 3, true);
///////////////////////////////////////////////////////////////////
//////////////////Transform Canny to Bitmap/////////////////////////////////////////
image1= Bitmap.createBitmap(imageCny1.cols(), imageCny1.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(imageCny1, image1);
return image1;
}
Related
currently, I'm working on a document scanner project who captures and filter document with different effects and color but I'm a beginner to work with OpenCV.
but, now I understand how medianBlurFilter , gaussianBlurFilter , cannyFilter and bilateralFilter works.
just I am starting to do this type of filter with the use of OpenCV but I can't understand how to achieve this.
Input :
How to achieve this?:
//bitmap is a normal document image
Bitmap newB = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newB);
canvas.drawColor(Color.argb(sp,255, 0, 0));
Mat src = new Mat();
Utils.bitmapToMat(bitmap, src);
Mat dst = new Mat();
Utils.bitmapToMat(newB, dst);
Core.addWeighted(src, 1f, dst, 0.5f, 0.5, dst);
//bitmapNew is a filtered document image
Bitmap bitmapNew = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dst, bitmapNew);
I use OpenCV (Java) and I want to change color of all the non transparent pixels in my Mat to black (colors defined in ARGB_8888 but could be another format)
How can I do that ?
Mat mat = new Mat();
bmp32 = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(bmp32, mat);
// and then ????
Thanks !
// allocate space as mixChannels requires so
Mat bgr = new Mat(mat.size(), CvType.CV_8UC3);
Mat alpha = new Mat(mat.size(), CvType.CV_8U);
List<Mat> src = new ArrayList<Mat>();
src.add(mat);
List<Mat> dst = new ArrayList<Mat>();
dst.add(alpha);
dst.add(bgr);
// A->alpha, RGB->bgr in reverse order
MatOfInt fromTo = new MatOfInt(0,0, 1,3, 2,2, 3,1);
mixChannels(src, dst, fromTo);
// now, make non-transparent parts black
Mat mask;
compare(alpha, Scalar(0), mask, opencv_core.CMP_EQ);
Mat res;
Core.bitwise_and(bgr, bgr, res, mask);
please help me with this as I am new to image processing.
I have the following images, there is glitterings/powder on the surface of the hand. How do I go about detecting these things on the hand?
I have tried with detecting by getting 70% of the max Intensity in the image. However, only image one works the rest does not. Could anyone how to suggest any methods that I can use to perform the detection please.(any available codes to try with will be good) Thank you?
Input Image 1: The only image that works with the above code
Input Image 2
Input Image 3
Desired Outcome
//convert from bitmap to mat
Mat mat = new Mat(bitmap1.getWidth(), bitmap1.getHeight(), CvType.CV_8UC3);
Utils.bitmapToMat(bitmap1, mat);
Mat grayMat = new Mat();
Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_BGR2GRAY);
//Log.d("TAGG","intensity" + mat.dump());
int rows = mat.rows();
int cols = mat.cols();
double maxIntensity = Core.minMaxLoc(grayMat).maxVal;
double minIntensity = 0.7 * maxIntensity;
Log.d("TAGG", "intensity" + maxIntensity);
Mat thresholdMat = new Mat();
Imgproc.threshold(grayMat, thresholdMat, minIntensity, maxIntensity, Imgproc.THRESH_BINARY_INV);
Bitmap outputBitmap = Bitmap.createBitmap(thresholdMat.cols(), thresholdMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(thresholdMat, outputBitmap);
I manage to draw two rectangles from an image I captured. The question is, how to crop them out and save them individually so that I can perform my OCR in each of it? I have tried searching but I can't find what I wanted...
What I have done so far ..
Mat imageMat = new Mat();
Mat resizeImg = new Mat();
Mat hierarchy = new Mat();
//Size(width,height)
Size imageSize = new Size(1000,800);
Utils.bitmapToMat(image, imageMat);
//Resize Image
Imgproc.resize(imageMat,resizeImg,imageSize);
//convert the resized image to bitmap
image = Bitmap.createBitmap(resizeImg.cols(), resizeImg.rows(),
Bitmap.Config.ARGB_8888);
//convert back to Mat
Utils.bitmapToMat(image, imageMat);
//Create rectangles
Imgproc.rectangle(imageMat,new Point(0,150), new Point(500,250), new Scalar(255, 0, 255),1);
Imgproc.rectangle(imageMat,new Point(0,500), new Point(650,650), new Scalar(255, 0, 255),1);
//What I have tried doing
Rect rectCrop = new Rect(0,150,500,250);
Mat image_output= imageMat.submat(rectCrop);
Bitmap Cropimage = Bitmap.createBitmap(imageMat.cols(), imageMat.rows(), Bitmap.Config.ARGB_8888);
Utils.bitmapToMat(Cropimage, image_output);
//TODO: save only the content in the rectangles to MAT
//testing purpose
Utils.matToBitmap(imageMat,image);
imageView.setImageBitmap(image);
This is how to get croped image with rectangular shape.
Rect rect = new Rect(x1, y1, x2, y2);
Mat cropedMat = new Mat(mat, rect);
if you want you can convert croped mat to bitmap
Bitmap Cropedimage = Bitmap.createBitmap(cropedMat.cols(), cropedMat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(cropedMat, Cropedimage);
i'm trying to gray the faces of all people in an image. While I can detect their faces and gray them into smaller mat(s), I'm unable to 'copy' the grayed faces to the original mat. Such that the end result will have a mat with all faces in gray.
faceDetector.detectMultiScale(mat, faceDetections);
for (Rect rect : faceDetections.toArray())
{
Rect rectCrop = new Rect(rect.x, rect.y, rect.width, rect.height);
Mat imageROI = new Mat(mat,rectCrop);
//convert to B&W
Imgproc.cvtColor(imageROI, imageROI, Imgproc.COLOR_RGB2GRAY);
//Uncomment below will grayout the faces (one by one) but my objective is to have them grayed out on the original mat only.
//Highgui.imwrite(JTestUtil.DESKTOP_PATH+"cropImage_"+(++index)+".jpg",imageROI);
//add to mat? doesn't do anything :-(
mat.copyTo(imageROI);
}
imageROI is a 3 or 4 channel image. cvtColor to gray gives a single channel output and the imageROI's reference to mat is probably destroyed.
Use a buffer for gray conversion and convert back to RGBA or RGB with dst as imageROI.
faceDetector.detectMultiScale(mat, faceDetections);
for (Rect rect : faceDetections.toArray())
{
Rect rectCrop = new Rect(rect.x, rect.y, rect.width, rect.height);
//Get ROI
Mat imageROI = mat.submat(rectCrop);
//Move this declaration to onCameraViewStarted
Mat bw = new Mat();
//Use Imgproc.COLOR_RGB2GRAY for 3 channel image.
Imgproc.cvtColor(imageROI, bw, Imgproc.COLOR_RGBA2GRAY);
Imgproc.cvtColor(bw, imageROI, Imgproc.COLOR_GRAY2RGBA);
}
The result looks like