drawMatches() throws CvException: Unsupported destination image - java

I'm drawing matches between my logo and my input image. The drawMatches function didn't work and thrown exception.
Here is my code:
Mat input = Imgcodecs.imread(inputAddress);
Mat logo = Imgcodecs.imread(logoList.getSelectionModel().getSelectedItem());
SIFT detector = SIFT.create(4, 3);
MatOfKeyPoint logoKeypoint = new MatOfKeyPoint();
MatOfKeyPoint inputKeypoint = new MatOfKeyPoint();
detector.detect(logo, logoKeypoint);
detector.detect(input, inputKeypoint);
Mat logoDes = new Mat();
Mat inputDes = new Mat();
detector.compute(logo, logoKeypoint, logoDes);
detector.compute(input, inputKeypoint, inputDes);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(logoDes, inputDes, matches);
HighGui.namedWindow("matches", 1);
Mat imgMatches = new Mat();
Features2d.drawMatches(logo, logoKeypoint, input, inputKeypoint, matches, imgMatches);
HighGui.imshow("matches", imgMatches);
The exception:
Caused by: CvException [org.opencv.core.CvException: cv::Exception: OpenCV(4.1.0) C:\Users\hennm\Downloads\opencv-4.1.0\modules\features2d\src\draw.cpp:128: error: (-2:Unspecified error) in function 'void __cdecl cv::_prepareImage(const class cv::debug_build_guard::_InputArray &,const class cv::Mat &)'
> Unsupported destination image:
> 'dst.type() == CV_8UC3 || dst.type() == CV_8UC4'
> where
> 'dst.type()' is 0 (CV_8UC1)
]
at org.opencv.features2d.Features2d.drawMatches_4(Native Method)
at org.opencv.features2d.Features2d.drawMatches(Features2d.java:116)
at sample.Controller.match(Controller.java:102)
Where sample.Controller.match(Controller.java:102) is the line Features2d.drawMatches(logo, logoKeypoint, input, inputKeypoint, matches, imgMatches);

Related

Java Opencv not detecting contours. imgproc.Drawcontours()

I am trying to develop a mobile application on Xamarin. Firstly I'm doing it for the android device. I want the Oncamera function to automatically detect the contours and measure the size of the object. As a primary step I am trying to detect the contours in real-time. Read lot of forms and many documents but nothing helped me
public Mat OnCameraFrame(CameraBridgeViewBase.ICvCameraViewFrame inputFrame)
{
Mat input = inputFrame.Rgba();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat gray = new Mat();
//Mat hierarchy = new Mat();
Imgproc.CvtColor(p0: input, p1: gray, p2: Imgproc.ColorRgb2gray);
Mat blur = new Mat();
Imgproc.GaussianBlur(gray, blur, new Size(7, 7), -2);
Mat thresh = new Mat();
Imgproc.Threshold(blur, thresh, 127, 250, Imgproc.ThreshBinary);
Mat edged = new Mat();
Imgproc.Canny(thresh, thresh, 25, 50);
Imgproc.Dilate(thresh, thresh, new Mat(), new Point(-1, 1), 1);
Mat hierarchy = thresh.Clone();
Imgproc.FindContours(hierarchy, contours, new Mat(),
Imgproc.RetrExternal, Imgproc.ChainApproxNone);
Java.Lang.JavaSystem.Out.Println("contours" + contours);
if (contours != null)
{
Java.Lang.JavaSystem.Out.Println("found contours");
for (int i = 0; i < contours.Count(); i++)
{
Imgproc.DrawContours(input, contours, i, new Scalar(255, 0, 0), -1);
}
}
else
{
Java.Lang.JavaSystem.Out.Println("no contours");
}
return input;
I used the above logic in the code. But my output in the application is displaying normal image without any contours drawn on it. If I return the "thresh", then canny edge detection is perfectly working. But Drawcontours is not showing up anything.
I used Contours.count() because my Xamarin ide is showing error for contours.Size();
I had a similar problem.
in my case I have replaced
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
with
IList<MatOfPoint> contours = new JavaList<MatOfPoint>();

How to convert Blob to Mat in java opencv?

I am trying to get images from MySQL database stored as blob and convert them into Mat object for image processing. I have a template image and want to know if that image is part of db image or not using matchTemplate() function. Here is my code:
String sql="select * from image_data where image_id="+1
try
{
query obj_query=new query(obj_connect);
ResultSet rs = obj_query.runSimpleQuery(sql);
while (rs.next())
{
Blob image_blob=rs.getBlob("original_image");
Mat img=Imgcodecs.imread(image_blob.toString());
}
}
catch (Exception e)
{
e.printStackTrace();
}
Mat templ=Imgcodecs.imread("templ.png");
Passing these images in findTemplate function:
MatchTemplate.findTemplete(img, templ, "ress.png", Imgproc.TM_SQDIFF);
And here is my findTemplate function:
public static void findTemplete(Mat img, Mat templ, int match_method)
{
double minVal;
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
Imgproc.matchTemplate(img, templ, result, match_method);
MinMaxLocResult mmr = Core.minMaxLoc(result);
minVal = mmr.minVal;
if(minVal<=0.75){
//do what you want
}
else
{
//do what you want
}
}
When I run it, it gives me an error:
OpenCV Error: Assertion failed (s >= 0) in cv::setSize, file C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\core\src\matrix.cpp, line 306
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: C:\builds\master_PackSlaveAddon-win32-vc12-static\opencv\modules\core\src\matrix.cpp:306: error: (-215) s >= 0 in function cv::setSize
]
at org.opencv.core.Mat.n_Mat(Native Method)
at org.opencv.core.Mat.<init>(Mat.java:37)
Line on which it gives me the error is:
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
How can I handle Blob image to pass it in Imagecodecs.imread() function? Or is there another technique to convert Blob to Mat?
Simple as this.
byte[] decodedString = Base64.decode(imageBlob, Base64.DEFAULT);
Bitmap img = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
Mat mat_img = new Mat();
Utils.bitmapToMat(img1, mat_img1);

Training SVM bad argument error

I followed the code in How to train an SVM with opencv based on a set of images? and I get the following exception
OpenCV Error: Bad argument (train data must be floating-point matrix) in cvCheckTrainData, file ......\src\opencv\modules\ml\src\inner_functions.cpp, line 857
Exception in thread "main" CvException [org.opencv.core.CvException: ......\src\opencv\modules\ml\src\inner_functions.cpp:857: error: (-5) train data must be floating-point matrix in function cvCheckTrainData
]
I followed the steps as mentioned in the comment. But still in vain.
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Mat classes = new Mat();
Mat trainingData = new Mat();
Mat trainingImages = new Mat();
Mat trainingLabels = new Mat();
CvSVM clasificador;
String path="C:\\java workspace\\ora\\images\\Color_Happy_jpg";
for (File file : new File(path).listFiles()) {
Mat img=new Mat();
Mat con = Highgui.imread(path+"\\"+file.getName());
con.convertTo(img, CvType.CV_32F,1.0/255.0);
img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32F));
}
System.out.println("divide");
path="C:\\java workspace\\ora\\images\\Color_Sad_jpg";
for (File file : new File(path).listFiles()) {
Mat img=new Mat();
Mat m=new Mat(new Size(640,480),CvType.CV_32FC3);
Mat con = Highgui.imread(file.getAbsolutePath());
con.convertTo(img, CvType.CV_32F,1.0/255.0);
img.reshape(1, 1);
trainingImages.push_back(img);
System.out.println((CvType.typeToString(img.type())));
trainingLabels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32F));
}
trainingLabels.copyTo(classes);
CvSVMParams params = new CvSVMParams();
params.set_kernel_type(CvSVM.LINEAR);
System.out.println(CvType.typeToString(trainingImages.type()));
CvSVM svm=new CvSVM();
System.out.println(svm.get_support_vector_count());
boolean b=svm.train(trainingImages, classes);
System.out.print(b);
}
}

adaptivethreshold gives an error (opencv, java)

I am trying to do adaptiveThresholding on an image but it gives me this error:
OpenCV Error: Assertion failed (src.type() == CV_8UC1) in adaptiveThreshold
I can't seem to understand why, here is my code:
Mat source = Highgui.imread("camera.jpg",
Highgui.CV_LOAD_IMAGE_COLOR);
Mat destination = new Mat(source.rows(),source.cols(),source.type());
Imgproc.cvtColor(source, destination, Imgproc.COLOR_RGB2GRAY);
Highgui.imwrite("grayscale.jpg", destination);
Mat source2 = Highgui.imread("grayscale.jpg",
Highgui.CV_LOAD_IMAGE_COLOR);
Mat destination2 = new Mat(source.rows(),source.cols(),source.type());
Imgproc.adaptiveThreshold(source2, destination2, 255,
Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 15, 4);
For adaptiveThreshold source should be 8-bit single-channel image, but you are loading source2 as colour,
So, Change the line
Mat source2 = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_COLOR);
to
Mat source2 = Highgui.imread("grayscale.jpg", Highgui.CV_LOAD_IMAGE_GRAYSCALE);
Also why to save and load destination image before adaptiveThreshold, pass it directly to adaptiveThreshold()

OpenCV Error: Assertion failed (scn == 3 || scn == 4) while using Watershed in OpenCV android sdk

I am working on an Android application that used the OpenCV-2.4.8 android sdk.
The following sample code tries to detect an object using the Watershed segmenter algorithm of the OpenCV library.
//bmp is the source bitmap that I am reading from a Drawable resource.
Mat mBackgroundMat = new Mat(new Size(bmp.getWidth(), bmp.getHeight()), CvType.CV_8UC3);
Utils.bitmapToMat(bmp, mBackgroundMat);
//Initialize the Mat Objects
Mat backgroundMat = new Mat();
Mat greyMatImg = new Mat();
Mat thresholdImg = new Mat();
Mat markerImg = new Mat();
//Erode and dillate
Imgproc.erode(mBackgroundMat, backgroundMat, new Mat(), new Point(-1, -1), 12);
Imgproc.dilate(backgroundMat, backgroundMat, new Mat(), new Point(-1, -1), 12);
// Imgproc.cvtColor(backgroundMat, backgroundMat, Imgproc.COLOR_RGB2BGR);
Imgproc.cvtColor(backgroundMat, greyMatImg, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(greyMatImg, thresholdImg, 0, 255, Imgproc.THRESH_BINARY_INV);
Imgproc.distanceTransform(thresholdImg, markerImg, Imgproc.CV_DIST_L2, Imgproc.CV_DIST_MASK_5);
Imgproc.cvtColor(thresholdImg, thresholdImg, Imgproc.COLOR_GRAY2BGR, 3);
Mat tempMat = new Mat(markerImg.rows(), markerImg.cols(), CvType.CV_32SC1);
Imgproc.cvtColor(markerImg, tempMat, CvType.CV_32SC1, 0);
Imgproc.watershed(thresholdImg, tempMat);
//Release unused mats.
tempMat.release();
backgroundMat.release();
greyMatImg.release();
markerImg.release();
//Output thresholdImg
I am getting the following error:
cv::error()(2566): OpenCV Error: Assertion failed (scn == 3 || scn == 4) in void cv::cvtColor(InputArray, OutputArray, int, int), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/imgproc/src/color.cpp, line 3648
Please help me in figuring out what I am doing wrong here.
Imgproc.cvtColor(markerImg, tempMat, CvType.CV_32SC1, 0);
I think it is this line - opencv is complaining about markerImg not being a 3 or 4 channel image. It looks like the Mats in this call have the same number of channels so perhaps you just need to convert between data types; the result of distanceTransform seems to give a CV_32FC1 so you could try just converting like this:
markerImg.convertTo(tempMat, CvType.CV_32SC1);
I had a similar error...
In my case, the error was because the Mat didn't have data.
Try to do this validation:
`if(!src.data) //where src is the Mat with the image
{
Log.d("Error","Adios");
exit(0);
}`
If you don't have data in src, then you won't convert this to Bitmap

Categories