Compare two objects in image - android

I need to compare two images to find the equality . I have searched a lot about AR and openCV. Already gone through compare two images in android and Tried OpenCV samples too . With OPENCV only ORB is free to use and it will compare images in GrayScale and thats not what i need.
P.S:- The need is i have 4 images of a object in my app. SO if user scan a real object using camera then i need to figure out the object in this scanned image does match any of the object in those 4 images or not. I know it way off-topic and also too broad as per SO standard but I really need help on this.
EDIT:- After trying some algos from github i stumble upon on This project . And the results are quite satisfying . I already have tested it with several templates . I am stuck here with one problem . I need to show to user whether the object found or not(a boolean) . How can i determine this if object is detected correctly or not ?
Putting some final step code below.
Point point1=new Point(sceneCorners.get(0,0));
Point point2=new Point(sceneCorners.get(1,0));
Point point3=new Point(sceneCorners.get(2,0));
Point point4=new Point(sceneCorners.get(3,0));
Imgproc.line(rgb, point1, point2, new Scalar(0, 255, 0), 4);
Imgproc.line(rgb, point2, point3, new Scalar(0, 255, 0), 4);
Imgproc.line(rgb, point3, point4, new Scalar(0, 255, 0), 4);
Imgproc.line(rgb, point4,point1, new Scalar(0, 255, 0), 4);
the 2 points are found on each detection . How can i determine that it detected the object or not ? Some things i already tried :
1. Check for rectangle formed with those points:- This can fail .
What is the recommended approach for solving this problem. I have searched a lot most of every sample on github but not found a solution for this .
Please let me know which approach should i follow ?

Related

Thresholding in Android using opencv

Not sure if this is the right way to ask, but please help. I have an image of a dented car. I have to process it and highlight the dents and return the number of dents. I was able to do it reasonably well with the following result:
The matlab code is:
img2=rgb2gray(i1);
imshow(img2);
img3=imtophat(img2,strel('disk',15));
img4=imadjust(img3);
layer=img4(:,:,1);
img5=layer>100 & layer<250;
img6=imfill(img5,'holes');
img7=bwareaopen(img6,5);
[L,ans]=bwlabeln(img7);
imshow(img7);
I=imread(i1);
Ians=CarDentIdentification(I);
However, when I try to do this using opencv, I get this:
With the following code:
Imgproc.cvtColor(source, middle, Imgproc.COLOR_RGB2GRAY);
Imgproc.equalizeHist(middle, middle);
Imgproc.threshold(middle, middle, 150, 255, Imgproc.THRESH_OTSU);
Please tell me how can I obtain better results in opencv, and also how to count the dents? I tried findcontour() but it gives a very large number. I tried on other images as well, but I'm not getting proper results.
Please help.
So you basically from the MATLAB site, imtophat does - Top-hat filtering computes the morphological opening of the image (using imopen) and then subtracts the result from the original image.
You could do this in OpenCV with the following steps:
Step 1: Get the disk structuring element
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (15, 15))
Step 2: Compute opening of the image and then subtract the result from the original image
tophat = cv2.morphologyEx(v, cv2.MORPH_TOPHAT, kernel)
This gives following result -
Step 3 - Now you could just manually threshold it or use Otsu -
ret, thresh = cv2.threshold(tophat, 17, 255, 0)
which gives you the following image -
Since the OP wants the code in Java, here is the probable code in Java:
private Mat topHat(Mat image)
{
Mat element = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(15, 15), new Point (0, 0));
Mat dst = new Mat;
Imgproc.morphologyEx(image, dst, Imgproc.MORPH_TOPHAT, element, new Point(0, 0));
return dst;
}
Make sure you do this on a gray scale image (CvType.8UC1) and then you can threshold suitably.

how to reduce wrong recognition using cascade classifier

Hello I'm tring to recognize a car using cascade classifier, android and opencv library. My problem is that my phone is marking almoust everything as a car.
I've created my code based on:
https://www.youtube.com/watch?v=WEzm7L5zoZE
and face detection sample. My app behave very strange cause marking looks like random. I even don't know if marking car is correct or maybe it is just some random behaviour. At the moment it is even marking my keyboard as a car. I'm not sure what can I improve. I don't see any progress between training it up to 5 or 14 stages
I've trained my file up to 14 stages
my code looks like this:
#Override
public Mat onCameraFrame(Mat aInputFrame) {
// return FrameAnalyzer.analyzeFrame(aInputFrame);
// Create a grayscale image
Imgproc.cvtColor(aInputFrame, grayscaleImage, Imgproc.COLOR_RGBA2RGB);
MatOfRect objects = new MatOfRect();
// Use the classifier to detect faces
if (cascadeClassifier != null) {
cascadeClassifier.detectMultiScale(grayscaleImage, objects, 1.1, 1,
2, new Size(absoluteObjectSize, absoluteObjectSize),
new Size());
}
Rect[] dataArray = objects.toArray();
for (int i = 0; i < dataArray.length; i++) {
Core.rectangle(aInputFrame, dataArray[i].tl(), dataArray[i].br(),
new Scalar(0, 255, 0, 255), 3);
}
return aInputFrame;
}
Try changing the below.
Using COLOR_RGBA2RGB with cvtColor as in sample code will not give a gray scale image. Try RGBA2GRAY
Increase the number of neighbors in detectMultiScale. Now it's 2. More neighbors means more confidence in result.
Hope there are enough samples to train with. A quick search and reading through books, gives an impression like thousands of images are needed for training. For e.g. around 10000 images are used for OCR haar training. For face training, 3000 to 5000 samples are used.
More importantly, decide if you really want to go with haar training for identifying a car. There could be better methods of vehicle identification. For e.g. for a moving vehicle we could use optical flow based techniques.

OpenCV - end cap control

I am attempting to draw a line (with line()) with square endings, but can not find any documentation telling me how to do it. So far all my lines end in little triangles.
Can this be done? Is its something to do with lineType?
EDIT: An example of my usage...
line(ptr_to_mat, Point(10,25), Point(30,25), Scalar(255,0,0,0),4, 8, 0);
EDIT: I should have mentioned, this is running on an Android device.
According to OpenCV docs, function line() will draw thick lines with rounding endings.
That said, you cannot directly get over this. But, you can draw it several times with thickness=1 or draw a filled rectangle instead to achieve your goal (both ugly though :():
line(ptr_to_mat, Point(10,23), Point(30,23), CV_RGB(255,0,0), 1, 8, 0);
line(ptr_to_mat, Point(10,24), Point(30,24), CV_RGB(255,0,0), 1, 8, 0);
line(ptr_to_mat, Point(10,25), Point(30,25), CV_RGB(255,0,0), 1, 8, 0);
line(ptr_to_mat, Point(10,26), Point(30,26), CV_RGB(255,0,0), 1, 8, 0);
You will get:
Also from the Docs - "The line is clipped by the image boundaries." - maybe you can clip the round edges out of the line by drawing the line inside of a Mat's Region Of Interest (ROI, a.k.a. submat). Basically you have to set the dimensions of the ROI with the size of the line minus the round tips. If this sound too complex, it is simpler than that.
It is not very elegant but considering that the clipping is done for free within the line drawing algorithm this probably more efficient than drawing several lines / rectangles.
Another thing, try to change the lineType parameter, it might change the tip rendering.
lineType:
8 (or omitted) - 8-connected line.
4 - 4-connected line.
CV_AA - antialiased line.
Or you can always implement your own line renderer?
I never said it would be pretty :D
the topic is a bit old but I faced this problem recently and I found a solution by using the library wxpython. Maybe it could help, here is a code example:
import wx
app = wx.App()
frame = wx.Frame(None, title="Draw on Image")
imgBit = wx.Bitmap(width=512, height=512, depth=1)
dc = wx.MemoryDC(imgBit)
pen = wx.Pen(wx.RED, 3)
pen.SetCap(wx.CAP_BUTT)
dc.SetPen(pen)
dc.DrawLines(((32, 32), (64, 32)))
dc.SelectObject(wx.NullBitmap)
imgBit.SaveFile("bitmap.png", wx.BITMAP_TYPE_PNG)
Hope it will help someone in the future

Create a Manga App

I've asked this before but apparently I was too broad on my description so i'll give it a try again. I'm using a library from Flandmark to actually use facial recognition of a person - figure out where their eyes, nose and mouth are. After that want I want to do is to generate a manga image of the person. I'm not sure how to do this. The first way I thought of was using a large database of manga images of specific areas such as the eyes, and map them to the original image. Question is, is there a way I can make the image look like a manga image in terms of background, colours, etc.
The first thing I thought would be useful is to get the size of the eyes and width of the mouth. This is done using this part of the Flandmark code:
flandmark_detect(input, bbox, model, landmarks);
// display landmarks
cvRectangle(orig, cvPoint(bbox[0], bbox[1]), cvPoint(bbox[2], bbox[3]), CV_RGB(255,0,0) );
cvRectangle(orig, cvPoint(model->bb[0], model->bb[1]), cvPoint(model->bb[2], model->bb[3]), CV_RGB(0,0,255) );
cvCircle(orig, cvPoint((int)landmarks[0], (int)landmarks[1]), 3, CV_RGB(0, 0,255), CV_FILLED);
for (int i = 2; i < 2*model->data.options.M; i += 2)
{
cvCircle(orig, cvPoint(int(landmarks[i]), int(landmarks[i+1])), 3, CV_RGB(255,0,0), CV_ED);
}
Any help would be appreciated as I don't know the best way to do this and im really stuck. Thanks

Graph/Plots on ANDROID

I am new to android and trying to learn creation or plotting of graphs in android. I've come across 2 libraries:
GraphView
AndroidPlot.
My intent would be to receive some sound file and plot it on a graph. So, for this purpose which library would be better. Also I wanna know, where I can see the complete implementation or definitions of these libraries i.e. the structure and code for the API's used in the above libraries.
Also I have tried some sample codes available on net. But I'm looking for a more sophiticated code which I could develop on eclipse ADT and hence can learn something out of it.
My intent would be to receive some sound file and plot it on a graph
Neither library does this by default. The libraries are used to plot a graph given a set of data points. Getting the data points from the sound file is up to you.
So, for this purpose which library would be better.
Either library should be fine once you get the data points.
Also I wanna know, where I can see the complete implementation or definitions of these libraries i.e. the structure and code for the API's used in the above libraries.
Check out the sources for GraphView and AndroidPlot.
I have used Achartengine some times and it works great. I modified it without difficulties.
If You are drawing simple Line Graph using canvas to draw the graph.
Use AndroidPlot. This code draw the content of Vector(in this case filled of zeros). You only have to pass the info of the wav file to the vector. And you can check this thread for the reading issue.
Android: Reading wav file and displaying its values
plot = (XYPlot) findViewById(R.id.Grafica);
plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 0.5);
plot.setRangeStep(XYStepMode.INCREMENT_BY_VAL, 1);
plot.getGraphWidget().getGridBackgroundPaint().setColor(Color.rgb(255, 255, 255));
plot.getGraphWidget().getDomainGridLinePaint().setColor(Color.rgb(255, 255, 255));
plot.getGraphWidget().getRangeGridLinePaint().setColor(Color.rgb(255, 255, 255));
plot.getGraphWidget().setDomainLabelPaint(null);
plot.getGraphWidget().setRangeLabelPaint(null);
plot.getGraphWidget().setDomainOriginLabelPaint(null);
plot.getGraphWidget().setRangeOriginLabelPaint(null);
plot.setBorderStyle(BorderStyle.NONE, null, null);
plot.getLayoutManager().remove(plot.getLegendWidget());
plot.getLayoutManager().remove(plot.getDomainLabelWidget());
plot.getLayoutManager().remove(plot.getRangeLabelWidget());
plot.getLayoutManager().remove(plot.getTitleWidget());
//plot.getBackgroundPaint().setColor(Color.WHITE);
//plot.getGraphWidget().getBackgroundPaint().setColor(Color.WHITE);
plot.setRangeBoundaries(-25, 25, BoundaryMode.FIXED);// check that, these //boundaries wasn't for audio files
InicializarLasVariables();
for(int i=0; i<min/11;i++){
DatoY=0;
Vector.add(DatoY);
}
XYSeries series = new SimpleXYSeries(Vector, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY,"");
LineAndPointFormatter seriesFormat = new LineAndPointFormatter(Color.rgb(0, 0, 0), 0x000000, 0x000000, null);
plot.clear();
plot.addSeries(series, seriesFormat);

Categories

Resources