I am trying to solve a problem of compositing two images in Java. The program will take a part of the first image and past it on the second image. The goal is to make the boundary between the two images less visible. The boundary must be chosen in such a way that the difference between the two images at the boundary is small.
My Tasks:
To write a method to choose the boundary between the two images. The method will receive the overlapping parts of the input images. This must first be transformed so that the boundary always starts from the left-top corner to the right-bottom corner.
NOTE:
The returned image should not be the joined image but gives which parts of the two images were used.
The pixels of the boundary line can be marked with a constant(SEAM). Pixels of the first image can be marked with integer 0, pixels of the second image with integer 1. After choosing the boundary line, the floodfill algorithm can be used to fill the extra pixels with 0 or 1.
NOTE: The image can be represented as a graph whereby each pixel is connected with its left, right, top and bottom neighbor. So using the flood fill will be like depth-first search.
The shortest path algorithm must be used to choose the boundary in order to make it small.
NOTE: I can not use any java data structure except Arrays (not even ArrayList)
Guys, am new in this area and am trying to solve it. What steps must I follow to solve this problem? or a pointer to a tutorial
I would do it so:
Choose the width of the border checked. At your will.
1. find the maximal possible shift in pixels. That is D.
2. For all possible shifts in the square (+-D,+-D) find the k (correlation quocient) for the border. The border is taken in the middle of the shift.
3. The shift that has the largest k is the best. Let it be taken for granted.
4. Now begin to move the border, checking it by "k" the same way. Find the place of it. Done.
If D is large and the process is long, do it in 2(or more) stages. On the first stages the step of counting k is large, the last stage has step of 1. You could also use previous filtering.
If the border or relative images' position could be turned, the algorithm doesn't change principally - only add to it trying for the best k among different slightly turned positions and later - turned border, too.
Related
So I'm trying to fill an ArrayList<Rectangle> with the bounds of each letter of an image file.
For example, given this .png image:
I want to fill an ArrayList<Rectangle> with 14 Rectangle(one rectangle for each letter)
We can assume that the image will contain only 2 colors, one for the background and one for the letters, in this case, pixels will be either white or red.
At first, I thought I could search for white columns in between the letters, then if I found a completely white column I could get for example the width by getting the lowest red pixel value and the highest red pixel value and width = maxX-minX and so on:
x = minX;
y = minY;
w = maxX-minX;
h = maxY-minY;
letterBounds.add(new Rectangle(x,y,w,h));
The problem is that there's no space in between the letters, not even 1 pixel:
My next idea was for each red pixel I find, look for a neighbor that hasn't been seen yet, then if I can't find a neighbor I have all the pixels to get the bounds of that letter. But with this approach, I will get 2 rectangles for letters like "i" I could then write some algorithm to merge those rectangles but I don't know how that will turn out with other multi part letters, and before I try that I wanted to ask here for more ideas
So do you guys have any ideas?
You can use the OpenCV cv2.findContours() function. Instead of using the cv2.drawcontours() function for drawing the contours, which will highlight the outline of the letter, you could instead draw a rectangle on the image by using the cv2.rectangle and by extracting the coordinates from cv2.findContours() function.
I think two step algorithm is enough to solve the problem if not using library like OpenCV.
histogram
seam calculation
1. histogram
C.....C..C...
.C.C.C...C...
. C.C....CCCC
1111111003111
dot(.) means background color(white)
C means any colors except background color(in your case, red)
accumulating the number of vertical pixels with non-background color generates histogram.
*
*
******..****
0123456789AB
It is clear the boundary exists at 6 and 7
2. seam calculation
Some cases like We, cannot be solved by histogram because there is no empty vertical lines at all.
Seam Carving algorithm gives us some hints
https://en.wikipedia.org/wiki/Seam_carving
More detail implementation is found at
princeton.edu - seamCarving.html
Energy calcuation for a pixel
The red numbers are not color values for pixels, but energy values calculated from adjacent pixels.
The vertical pathes with minimal energy give us the boundary of each characters.
3. On more...
Statistical data is required to determine whether to apply the seam carving or not.
Max and min width of characters
Even if histogram give us vertical boundaries, it is not clear there are two or more characters in a group.
I have an array with the coordinates of the center of small circles which have the same radius. I know how to find when the mouse is over a circle, but my array is big and I want the fastest way to calculate this operation.
Is there a way of finding if the mouse is over a circle without looping all the array for each movement of the mouse?
Initially, set up some 'zones' for quicker reference:
Separate the whole surface into a small number of rectangles that don't intersect.
For each of these rectangles, list all circles that are at least partially contained in it. (A circle may end up listed in multiple rectangles, but that's okay.)
Every time you want to check whether the mouse is over a circle, you won't have to go through the whole array of circles. Instead:
Figure out which rectangle you're in.
Check only the circles that are listed under that rectangle.
This looks like a problem of optimizing the boundary check for a large number of items. The approach of going linearly does not scale well for thousands of circles.
This is a good topic to read on the net. But first, without going there, I'll try to explain (as an exercise) what I would explore. I would create a binary tree and partition the space, then instead of using an array I would put the circle points in such a tree. Looking the tree elements that are closer to the actual X,Y location becomes a matter of doing a binary search on the tree. The you have the closest point as a result of that search and can check for collision on it. There is still more to be done to the algorithm, and further optimizations are needed. For example, how to check for more points and not only the final one? Potentially I need a tree for the X coordinate, and another for the Y coordinate, etc... But I would explore these ideas. I will come back to this post and expand my reply with an actual example and a more concrete solution.
What if you check the coordinates that are r(radius) distance from the mouse? Then you could narrow your search down in the array if it is ordered.
I am new to image processing and to opencv in particular.
I am working on an OCR project in which i need to identify numbers.
This is my image to process:
Lets say i already optimized the image, my questions are:
In the image the number are always apeared several times, lets say i found the contours, so how can i know which one if the the best one to process?
How can I know in what angle I need to rotate each contour to make It stright?
In the image the number are always apeared several times, lets say i found the contours, so how can i know which one if the the best one to process?
You want always the biggest number, because they are least warped by perspective. So you always want the numbers in the middle of the image, because they are also n the middle of the ball.
How can I know in what angle I need to rotate each contour to make It stright?
Have a look at rotated rect. I explained how to find the angle in this thread.
Since you always have a perfectly centered ball, you should think about using mapping to "unwarp" your ball (so do a projection like from the globe onto a map). It should be pretty straightforward afterwards to find the numbers on the flat image.
Edit: Since you only have 10 numbers you might also "brute force" the solution with a big enough training set. So just throw all numbers you detect into a classifier and keep the most likely solution.
1) I agree with #Sebastian in the first part. Exploit the fact that in your scenario the numbers are placed in the surface of a ball, so first select the blobs inside a centered region of interest.
2) The contours shown in the image are not rotated (the numbers are). Instead of "rotating" these bounding boxes, which seems to be quite a headache, I'd rather use them combined with rotation invariant keypoints. I'll clarify this:
a) You know where your numbers are, so you don't have to search in the entire image. OK, keep these already selected regions in mind.
b) You can take "straight" samples of the numbers 0-9 and use them as ground truth.
c) You can perform a matching search between each "ground truth" image and each candidate region. Now, forget the scale/rotation: use scale/rotation invariant keypoints! Something like this:
Again, notice that you have already selected the region-of-interest, so in your case the search will consist on checking the number of matches (number of blue lines) between each of the registered numbers and your candidate. I think it worth a try! :)
You can find more info on the different keypoints available in opencv here.
Hope that it helps!
We are trying to crop the relevant area of an image (photo) with a square aspect ratio (1:1), similar to what Facebook does when creating thumbnails.
In our case, it doesn't really matter if the crop has the original height (or width when the image orientation is portrait h>w) of the image to be processed or the auto-crop is resizing itself as well
I am thinking of algorithms like comparing objects with background or focus or something like a heat-map, combining colors and/or areas to find the most relevant part. There could be several ideas/methods to find the main part of the image to be used, similar to face detection.
We are looking for a Java (Android)-based solution or anything that can be adopted for Java / Android. Any help or idea would be greatly appreciated! Thank you!
I would do this in two steps, where the initial step is more robust and the second could be based on, for example, entropy. For the first step, you can use SURF which is relatively common nowadays and I would expect to find Java implementations of it. SURF will give a set of key points that it considers important to describe your image. Considering where these key points are in your image, you have a set of (x, y) coordinates from which you use to reduce the area of your initial image to that which encloses this set of points. Now, since these key points might be anywhere in your image, you will probably want to discard some of them (i.e., those that are too far from the others -- outliers). A very simple way to do this discarding step is considering the convex hull from the initial set of key points, from there, you can peel this hull multiple times. Each time you "peel" it, you are effectively discarding the points in the current convex hull.
Here is a sample for such first step:
f = Import["http://fohn.net/duck-pictures-facts/mallard-duck.jpg"];
kp = ImageKeypoints[f, MaxFeatures -> 200];
Show[f, Graphics[{PointSize[Medium], Red, Point[kp]}]]
After peeling once the convex hull formed by the key points and trimming the image according to the bounding rectangle of the remaining points:
From the image above, you can decide which sub-region of it to pick based on some other method. One that is apparently common is the one used by Reddit, which successively remove slices of lesser entropy from the image. Quickly searching for it, I found one such implementation at https://github.com/christopherhan/pycrop/blob/master/pycrop.py#L33, it is very simple.
Another different kind of method that you might wanna try is called Seam-Carving. Also note that depending on how large is the initial image, it is unlikely that cropping a small piece of it will give anything relevant. In those cases, it is more interesting to first resize the image and then apply the relevant methods.
I have an image such as this:
and I need to calculate the orientation of it. In this case the shape is pointing towards the top left of the screen. Accuracy isn't hugely important as long as 3 or 4 calculations average out to within 5 degrees or so of the actual orientation (it will be moving slightly).
Can anyone point me towards an algorithm to do this? I don't mind if the orientation is returned as a double or as a vector.
If the image is always T-shaped, you can simply get the furthest pair of pixels, then find the furthest pair from either both of those (the edges of the T), find which is further from the other two, draw a line from that one to the middle point of those two.
You can further refine it by then finding the base of the T by comparing the middle line with the edges of the base, and adjusting the angle and offset until it is actually in the middle.
The definitive solution is impossible I guess, since requires image recognition. I would project the 2D image onto axis, i.e. obtain the width and height of the image and get direction vector from these values taking them as components.
First, a couple of assumptions:
The center and centroid are "close"
The descending bar of the T is longer than the cross-bar
First, determine the bounding rectangle of the image and find the points of the image that lie along this rectangle. For points that lie along the line and are a certain distance from one another (say 5 pixels to pick a value) you'll need to only take 1 point from that cluster. At the end of this you should have 3 points, i.e. a triangle. The shortest side of the triangle should be the cross-bar (from assumption 2), i.e. find the two points closest to each other. The line that is perpendicular to the line crossing those two points is then your orientation line, i.e. find the angle between it and the horizontal axis.
I would try morphological skeletonization to simplify the image, followed by some straightforward algorithm to determine the orientation of the longer leg of the skeleton.
The solution in the end was to use a Convex Hull Algorithm, which finds the minimum number of points needed to enclose a shape with a bound.