So I have been trying to get coordinates of the corner in a QR 1.
But the output from detectAndDecode functions return some string that looks like "[D#fb258ec".
What have I done wrong? Or is the vertices not meant what I think they mean?
Just starting out on the journey to learn openCV and Android, the process has been though...
Any help or advice is much appreciated, thanks.
A snippet of what I think is the main part is shown below.
Edit 1: Added link to QR and more code.
#Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mat1 = inputFrame.gray();
Mat clrCrr = new Mat();
Imgproc.cvtColor(mat1, clrCrr, Imgproc.COLOR_GRAY2BGR);
QRCodeDetector decoder = new QRCodeDetector();
Mat QR = new Mat(); //Mat for QR code
Mat points = new Mat(); // points of QR Mat
Mat dst = new Mat(); //Output frame
runOnUiThread(new Runnable() {
public void run() {
Handler h = new Handler();
String data = decoder.detectAndDecode(clrCrr, points,QR); //Decode QR
EditText editText = findViewById(R.id.editText);
points.convertTo(points,CvType.CV_64FC3);
editText.setText("Point 1 " +points.get(0,0) );
Log.d("Test", String.valueOf(points.get(0,1)));
h.postDelayed(this,3000);
}
});
Imgproc.threshold(mat1, dst, 100, 200, Imgproc.THRESH_BINARY); // Threshold and return dst
return dst
}
I think I found the solution.
Just need to use
Arrays.toString(points.get(0,0))
instead of just
points.get(0,0)
This will then return a coordinates like [1142.0, 230.0]
Related
I am developing one Android application using OpenCV where I have to implement Background Subtraction. I am able to see some frames in grayscale and background removed, it only lasts for a while though, and then the application crashes.
Technique used: BackgroundSubtractorMOG2
This is my snippet of OnCameraFrame
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
Mat frame = inputFrame.rgba();
Mat mRgb = new Mat();
Mat mFGMask = new Mat();
BackgroundSubtractorMOG2 mog2 = Video.createBackgroundSubtractorMOG2();
Imgproc.cvtColor(frame, mRgb, Imgproc.COLOR_RGBA2RGB);
mog2.apply(mRgb, mFGMask);
Imgproc.cvtColor(mFGMask, frame, Imgproc.COLOR_GRAY2RGBA);
return frame;
}
Thanks in advance.
I was able to solve my issue.
new Mat() which is used was causing an issue of memory management. It has to be initialized just once in onCameraViewStarted and the returning Mat has to be released in onCameraViewStopped. After modifying the code as per suggestions through the OpenCV community, I was able to execute my application properly.
1. Declare at the first
private Mat mRgb;
private Mat mFGMask;
private Mat frame;
private BackgroundSubtractorMOG2 mog2;
Initialize in onCameraViewStarted
public void onCameraViewStarted(int width, int height) {
mRgb = new Mat();
mFGMask = new Mat();
mog2 = Video.createBackgroundSubtractorMOG2();
}
Release the returning frame in onCameraViewStopped
public void onCameraViewStopped() {
frame.release();
}
For full code: https://github.com/rishirajrsawant/OpenCV-Background-Subtraction
I have an image composed of 3 objects and I need to extract those objects. I tried Watershed algorithm but it doesn't work as expected.
i don't have a good understanding of how this algorithm work so I can't figure out the real problem.
Here is my code
public Mat steptowatershed(Mat img)
{
Mat threeChannel = new Mat();
Imgproc.cvtColor(img, threeChannel, Imgproc.COLOR_BGR2GRAY);
Imgproc.threshold(threeChannel, threeChannel, 0, 255, Imgproc.THRESH_BINARY_INV + Imgproc.THRESH_OTSU);
Mat fg = new Mat(img.size(),CvType.CV_8U);
Imgproc.erode(threeChannel,fg,new Mat());
Mat bg = new Mat(img.size(),CvType.CV_8U);
Imgproc.dilate(threeChannel,bg,new Mat());
Imgproc.threshold(bg,bg,1, 128,Imgproc.THRESH_BINARY_INV);
Mat markers = new Mat(img.size(),CvType.CV_8U, new Scalar(0));
Core.add(fg, bg, markers);
Mat result1= new Mat();
Imgproc.cvtColor(img, img, Imgproc.COLOR_BGRA2BGR);
WatershedSegmenter segmenter = new WatershedSegmenter();
segmenter.setMarkers(markers);
result1 = segmenter.process(img);
return result1;
}
public class WatershedSegmenter
{
public Mat markers=new Mat();
public void setMarkers(Mat markerImage)
{
markerImage.convertTo(markers, CvType.CV_32SC1);
}
public Mat process(Mat image)
{
Imgproc.watershed(image,markers);
markers.convertTo(markers,CvType.CV_8U);
return markers;
}
}
Here is the original image
Here is the result image
I need the extract all 3 objects later.
I wish you guys help me solve this issue.
I'm working with sift using opencv sdk for android
I'm facing difficulties in drawing matches between two images using the
Feature2d.drawMatches()
whenever I run the app it goes through all the steps but stopped when reaching the draw function.
Here's the full code:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("opencv_java");
System.loadLibrary("nonfree");
}
private ImageView imageView;
private FeatureDetector detector = FeatureDetector.create(FeatureDetector.SIFT);
DescriptorExtractor descriptorExtractor=DescriptorExtractor.create(DescriptorExtractor.SIFT);
DescriptorMatcher descriptorMatcher= DescriptorMatcher.create(3);
Bitmap inputImage;
Bitmap inputImage2;
Bitmap out;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(OpenCVLoader.initDebug()){
Toast.makeText(this,"Hiii",Toast.LENGTH_SHORT).show();}
inputImage = BitmapFactory.decodeResource(getResources(), R.drawable.object);
inputImage2 = BitmapFactory.decodeResource(getResources(), R.drawable.objecttest);
out = BitmapFactory.decodeResource(getResources(), R.drawable.test);
imageView = (ImageView) this.findViewById(R.id.imageView);
sift();
}
public void onResume() {
super.onResume();
}
public void sift() {
Mat rgba = new Mat();
Mat rgba2 = new Mat();
Mat desc=new Mat();
Mat desc2=new Mat();
MatOfDMatch matches=new MatOfDMatch();
Mat output=new Mat();
Utils.bitmapToMat(inputImage, rgba);
Utils.bitmapToMat(inputImage2, rgba2);
Utils.bitmapToMat(out, output);
MatOfKeyPoint keyPoints = new MatOfKeyPoint();
MatOfKeyPoint keyPoints2 = new MatOfKeyPoint();
Imgproc.cvtColor(rgba, rgba, Imgproc.COLOR_RGBA2GRAY);
Imgproc.cvtColor(rgba2, rgba2, Imgproc.COLOR_RGBA2GRAY);
detector.detect(rgba, keyPoints);
detector.detect(rgba2, keyPoints2);
descriptorExtractor.compute(rgba,keyPoints,desc);
descriptorExtractor.compute(rgba2,keyPoints2,desc2);
descriptorMatcher.match(desc,desc2,matches);
Features2d.drawMatches(rgba,keyPoints,rgba2,keyPoints2,matches,output);
Utils.matToBitmap(output, out);
imageView.setImageBitmap(out);
}
}
I also need to know whether sift is the best choice for the use of detecting complicated objects in real time?
Edit 1: I notice now that I'm getting the following errors
OpenCV Error: Assertion failed (0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols && 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows)
Fatal signal 11 (SIGSEGV), code 2, fault addr 0x12ce08e0 in tid 9971
Problem solved:
the error I've mentioned was preventing the image from being displayed for some reason( maybe the difference of properties between the image view and the image we want to display let's say the dimensions in some cases
actually I'm not sure about the previous point but it was mentioned out there, and the solution was to set the image view to be dynamically resized according to the image but that didn't work for me)
My problem was solved by replacing these instructions:
Features2d.drawMatches(rgba,keyPoints,rgba2,keyPoints2,matches,output);
Utils.matToBitmap(output, out);
imageView.setImageBitmap(out);
with the following:
Scalar RED = new Scalar(255,0,0);
Scalar GREEN = new Scalar(0,255,0);
MatOfByte drawnMatches = new MatOfByte();
Features2d.drawMatches(rgba,keyPoints,rgba2,keyPoints2,matches,output,GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);
Bitmap imageMatched = Bitmap.createBitmap(output.cols(), output.rows(), Bitmap.Config.RGB_565);//need to save bitmap
Utils.matToBitmap(output, imageMatched);
imageView.setImageBitmap(imageMatched);
I didn't actually get the difference, so further help describing this will be so helpful, but hope this can temporarily help people having the same problem
I have searched everywhere for a solution but I haven't found any. I know this is a recurrent question, so I'll try to be precise.
I want to perform color segmentation in HSV using Android and OpenCV. I have an array of HSV samples corresponding to the color I want to segment, from which I obtain mean and std in order to obtain a range of values like:
lowerBoundH = new Scalar(meanSamples[0]-stdSamples[0]);
lowerBoundS = new Scalar(meanSamples[1]-stdSamples[1]);
upperBoundH = new Scalar(meanSamples[0]+stdSamples[0]);
upperBoundS = new Scalar(meanSamples[1]+stdSamples[1]);
Once I obtain these ranges for H, S and V I do the following (I only work with channels H & S):
mH = new Mat();
mS = new Mat();
List<Mat> channels = new ArrayList<Mat>(2);
// convert inputFrame to HSV for segmentation
Mat hsvFrame = new Mat();
convertToHSV(inputFrame, hsvFrame);
Core.split(hsvFrame, channels);
// get H&S channels of the HSVimage
mH = channels.get(0);
mS = channels.get(1);
if(mH!=null & mS!=null){
mHinRange = new Mat();
mSinRange = new Mat();
Core.inRange(mH, lowerBoundH, upperBoundH, mHinRange);
Core.inRange(mS, lowerBoundS, upperBoundS, mSinRange);
Mat filtered = new Mat(hsvFrame.height(), hsvFrame.width(), CvType.CV_8UC1, new Scalar(4));
Core.bitwise_and(mHinRange, mSinRange, filtered);
Mat aux = new Mat();
Mat mRgb = new Mat();
inputFrame.copyTo(mRgb);
Imgproc.cvtColor(filtered, mRgb, Imgproc.COLOR_GRAY2BGR, 0);
Imgproc.cvtColor(mRgb, aux, Imgproc.COLOR_BGR2RGBA, 0);
return aux;
}else{
Log.v("NULL","H OR S CHANNELS ARE NULL");
return null;
}
Then, I convert that segmented Mat to Bitmap in order to display it in an ImageView like so:
Bitmap bmp = null;
Mat tmp = new Mat(result.height(),result.width(), CvType.CV_8UC1, new Scalar(4));
try {
bmp = Bitmap.createBitmap(tmp.cols(), tmp.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(tmp, bmp);
}catch (CvException e){Log.d("Exception",e.getMessage());}
qrImage.setImageBitmap(bmp);
But when I display the resulting image I get a completely black image. I know this is wrong because the camera is facing directly to the colored object I want to segment.
What am I doing wrong?
What a stupid mistake. I was creating the Bitmap from the empty tmp Mat.
Instead, I need to create it using the result Mat:
Bitmap bmp = null;
try {
bmp = Bitmap.createBitmap(result.cols(), result.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(result, bmp);
}catch (CvException e){Log.d("Exception",e.getMessage());}
qrImage.setImageBitmap(bmp);
I am trying to change the hue of image store in matrix. I got a hue channel using split() function but i am not able to change its hue. I am using the function set(Scalar scalar) to change its hue, but i don't see any change in image.
Mat eyeball_HSV = new Mat();
Mat dest = new Mat();
Mat eye = new Mat();
eye = mRgba.submat(eye_template);
List<Mat> hsv_channel = new ArrayList<Mat>();
Imgproc.cvtColor(eye, eyeball_HSV, Imgproc.COLOR_RGB2HSV, 0);
// get HSV channel
//hsv_channel[0] is hue
//hsv_channel[1] is saturation
//hsv_channel[2] is visibility
Core.split(eyeball_HSV, hsv_channel);
try
{
hsv_channel.get(0).setTo(new Scalar(145,25,45));
Log.v(TAG, "Got the Channel!");
}
catch(Exception ex)
{
ex.printStackTrace();
Log.v(TAG, "Didn't get any channel");
}
Imgproc.cvtColor(eyeball_HSV, dest, Imgproc.COLOR_HSV2RGB);
Imgproc.cvtColor(dest, eye, Imgproc.COLOR_RGB2RGBA);
Just change the code
hsv_channel.get(0).setTo(new Scalar(145,25,45));
to
hsv_channel.get(0).setTo(new Scalar(145)); // whatever your value
hsv_channel.get(0) is single channel Mat so your Scalar value should be with single.
Edit:-
Yo can see the OpenCV camera preview example here
On Tutorial1Activity.java you can see a method
public Mat onCameraFrame(CvCameraViewFrame inputFrame)
Add these lines on this method
src = inputFrame.rgba();
Imgproc.cvtColor(src, hsv,Imgproc.COLOR_RGB2HSV );
Core.split(hsv, hsv_channel);
// Imgproc.equalizeHist(hsv_channel.get(0), hsv_channel.get(0));
hsv_channel.get(0).setTo(new Scalar(64));
Core.merge(hsv_channel, hsv);
Imgproc.cvtColor(hsv, src,Imgproc.COLOR_HSV2RGB );
//return hsv_channel.get(0);
return src;