I have to stitch two images and I use openCV4Android.I read docs and some threads in about stitching images,for example: Panorama – Image Stitching in OpenCV , Homography between images using OpenCV for Android , Stitch multiple images , Error matching with ORB in Android and others.At first,it seems easy.But the result is strange!Below,you can see two images that I used for test and result:
Here is "image1":
This is "image2":
You can see drawed features:
And this is result of warping image1:
What I did wrong?Or it may be I did not understand good?
Quick answer:
I would say that you don't have enough overlap between your images. If you look at your matches (what you call "drawed features"), most of them are wrong. As a first test, try to stitch two images that have, say, 80% overlap.
More details:
Big picture:
When you stitch two images, you assume that there exists an affine transform (your "homography") that will project features from one image onto the other one. When you know this transform, then you know the relative position of your images and you can "put them together". If the homography transform that you find is bad, then the stitching will be bad as well.
How do we find the homography transform, then?
First of all, you detect features (with your FeatureDetector) on both images.
Then, you describe them (with your DescriptorExtractor). Basically this creates a representation of your features, so that you can compare two features and see how similar they are.
You match (using your DescriptorMatcher) features from the first image to the features from the second image. It means that for each feature in the first image, you try to find the most similar one in the second image. Those are your "drawed features".
From those matches, you use an algorithm called "RANSAC" to find the homography transform corresponding to your data. The idea is that you try to find a set of matches from all your "drawed features" that makes sense geometrically.
But why doesn't it work here?
If you look at your "drawed features", you will see that only a few ones on the "Go" part of "Google" and some in the boorkmarks correspond, when the others are wrong. It means that most of your matches are bad, and then it makes it possible to find a homography that works for this data, but that is wrong.
In order to have a better homography, you would need much more "good" matches. Consequently, you probably need to have more overlap between your images.
NOTE: try your code with the images used in "Panorama – Image Stitching in OpenCV"
Related
I need the code to add invisible watermark to another image in Android
As the comments mentioned, Stackoverflow isn't a free coding service. I will provide you with a high level design advice from which you can implement your own code.
Invisible watermark could just be metadata. The point is to make your particular photo unique and identifiable, right? I would recommend you looking into image metadata manipulation for a simple solution.
That being said, if you are looking for some high tech stealthy watermarking, then you might be looking for pixel manipulation. You can change a few of the pixel colors so if it's compared with the original image with the naked eye, it looks identical but if compared with their base64 encoding you can see a difference. Simply create your own pattern as some sort of signature to attach to images to identify them.
Both method allows you to determine if an image is yours due to the "watermark" you leave on it.
I am trying to develop an android app, that matches template picture on camera screen with actual image which is scanned through camera check image to get clarified
the four green circles on the template image appearing on camera screen should match with the four circles appearing in the background image which I will be scanning through the camera, exactly as shown in fig... once the four circles of template image matches with four circles of background image, a toast will get appeared
How to achieve this? i ve gone through openCV template matching, but couldnt achieve this..
Thanks :)
There are many algorithms in opencv used to match images. I recommend finding features and descriptors of the two images using sift or surf and use brute force matcher or falnn matcher. and check the good matches if there are enough good matches then the object is found and toast the message.
I would just try to find the four circles using HoughCircles and check their positions.
Parameter setting for HoughCircles will be a bit tricky, so try with different values until you see the stable result. The min/max Radius parameters should be as narrow as possible to save computing time and avoid invalid results.
My app is loading a large image (a house floorplan), then drawing touch-reactive objects (furniture, lamps etc.) on the image. I have a base image file included with my app but the objects come from coords in my database.
I've successfully deployed the app in multiple iterations, but now I need to use larger base images and BitmapFactory is causing an OutOfMemory exception on many devices (both old and new devices; anything with < 32MB heap seems to crash). I've read the 157 OOM questions on SO, but I'm afraid the link they all seem to point to won't help me since resolution / zooming is critical to the app's function.
I've tried to test the device's available memory before loading, but the results are spotty at best (some devices like the galaxy S3 report plenty of heap but still crash). I've also tried decreasing resolution but the image became unusable when reduced to a safe size based on the above test.
Is there another way to implement this design without ever using bitmaps?
I need to:
Load large base image
Create clickable shapes on top of the base image, maintaining their position / scale relative to the base image
BONUS: in the iOS version of my app, I can do SVG-style text scaling so a long label on a small object will stay inside the object
instead of running across the map(and will be invisible until the
image is zoomed). Replicating this in android would make me a happy
code monkey.
I can post code if needed, but you've all seen it before (almost all of it came from SO).
Thanks in advance for reading, and for any help you can give.
you have a few options:
break your large image into tiles, load these tiles into an array, and move a camera object around and only load tiles that need to be drawn, as the comments suggest.
make your image small and scale it up using 'android:scaletype`
Draw lines and curves on a Canvas object at runtime.
Use OpenGL
The appropriate solution really depends on how you want it to look. Tiling will take more dev effort but will look better, just be careful that you are properly cleaning up any tiles that aren't being drawn...
dynamically scaling will be easier, but you cannot guarantee the image won't be blurry.
Drawing on a Canvas object at runtime could work well-- just use Lines of different width and circles and Rects etc.
Using OpenGL will have the steepest learning curve, and might be overkill. This depends on your purpose.
You might like to look into using a "largeHeap"
http://developer.android.com/reference/android/R.styleable.html#AndroidManifestApplication_largeHeap
Here are some options:
1) Use tiles. Use tiles and dynamically load your data. Honestly, this is the best solution. With this solution you can load arbitrarily large images.
I've successfully used this approach for an endless paint canvas and it works quite well. You really only need to draw what is directly visible to the user. Tiles is a way to cast away pieces you don't need. A pyramid of tiles (where you pre-downsample your images and create more tiles), allows you to do this in a clean and fast way.
2) Use native code. The memory restrictions on native code are not the same as Java code. You can get away with allocating more memory.
3) Use OpenGL. Once again, the memory restriction for OpenGL are not the same as Java code.
4) Convert your original plan to an SVG and use an SVG library like this one.
5) Use "largeHeap". I strongly discourage this, as I think a largeHeap is rarely the solution, there are generally cleaner ways to approach the problem.
if the image is static , you might wish to use this nice library:
https://github.com/ManuelPeinado/ImageLayout
if the library doesn't support auto-downsampling of the image, you should do it by yourself, in order to use the best image for the current device (so that you won't get OOM).
for auto-sizing text , you might have some luch with the next post:
Auto-fit TextView for Android
I'm using Tesseract ORC library to extract text from images taken on screens. Problem is that most modern cameras also captures the pixel on a display while taking a photo.
Is there anyway to apply like a filter or threasholding to the bitmap to "extract" the text to a clearer one for better results with tesseract?
Se example, before processing:
After processing (threshold effect in photoshop):
Tesseract has a built-in threshold method, TessBaseAPI#ThresholdRect. Have you tried that? If so, what problems did you have with it?
If it didn't work so well on some pictures, you may want to try looking up some "mean" or "adaptive" threshold algorithms, since it looks like Tesseract's is a straight threshold, so it may not adapt well to darker/lighter images without some tweaking.
I am trying to port some code from a regular Java program into the Android platform. Unfortunately, a significant part of the program involves manipulating images, and Java's AWT was taken away from me. I am trying to replace awt.BufferedImage with Bitmap, and was hoping that the only differences between the two classes would be their interfaces. I read some of the documentation, and it looked like that is true, but after wrapping all of the image stuff into a nice little class and testing almost-the-same code on both my development machine and an actual phone, one program works and the other does not. So:
The encoding for color does not change - right? It is still 0xAARRGGBB - right?
The images themselves are not changed - right? When I put an image into res/drawable, it is exactly the same image. Most notably, they don't alter the resolution in any way - right?
Accessing the pixels is essentially the same - right? I essentially replaced all of my get/setRGB(x,y,RGB) with get/setPixel(x,y,color). There are no changes to the method of indexing into the grid - is there?
Solved: when opening the image, I failed to create a BitmapFactory.Options() with inDither set to false. The BitmapFactory then failed to produce an exact copy, putting some alterations in the resulting Bitmap in order to make it more pleasing for display.