Randomly Generating Patterns Using Hexagonal Images - android

Okay so I have these images:
Basically what I'm trying to do is to create a "mosaic" of about 5 to 12 hexagons, with most of them roughly centralised, and where all of the lines meet up.
For example:
I'm aware that I could probably just brute-force it, but as I'm developing for Android I need a faster, more efficient and less processor-intensive way of doing it.
Can anybody provide me with a solution, or even just point me in the right direction?

A random idea that I had is to go with what Deepak said about defining a class that tracks the state of each of its six edges (say, in an int[] neighbor in which neighbor[0] states if top edge has neighbor, neighbor[1] states if top-right edge has neighbor, and so on going clockwise)
Then for each hexagon on screen, convert its array to an integer via binary. Based on that integer, use a lookup table to determine which hexagon image to use + how it should be oriented/flipped, then assign that hexagon object to that image.
For instance, let's take the central hexagon with four neighbors in your first screenshot. Its array would be [1, 0, 1, 1, 0, 1] based on the scheme mentioned above. Take neighbor[0] to be the least-significant bit (2^0) and neighbor[5] to be the most-significant bit (2^5), and we have [1, 0, 1, 1, 0, 1] --> 45. Somewhere in a lookup table we would have already defined 45 to mean the 5th hexagon image, flipped horizontally*, among the seven base hexagon icons you've posted.
Yes, brute-force is involved, but it's a "smarter" brute-force since you're not rotating to see if a hexagon will fit. Rather, it involves a more efficient look-up table.
*or rotated 120 degrees clockwise if you prefer ;)

Nice and tricky question. What you can start with is define object for each image which has attributes that specify which edge has a line attached to it. Then while adding the images in the layout you can rotate it in such a way that the edge with line in one image lies adjacent to the other image's edge with line. It may be little complicated but I hope you can at least start with something like this.

Related

Nutrition Facts Detection with OpenCV

I would like to detect some nutrition facts on food package with an Android Application, with OpenCV.
So far I managed to do it with one image of a nutrition table, but of course it only works with this one.
The goal is to detect and retrieve the value of Energy, Proteines, and Glucides, for 100g of product. These informations are present in almost every table, that is why I focus only on them for the moment.
So I was wondering if there a good method to do so ? For the moment, I try to detect each block of text, recognise it with Tesseract, and if it fits the word I'm looking for, I get the corresponding column and line in the picture, to finally get the value I want.
Is there any way to track the words straightly, and get the value that fits best in the image (in terms of alignement with the "100g" column).
Typical image : hpics.li/4231f79
Sorry if my problem is not well explained, just ask if something is not clearor if you want me to explain more what I've done for the moment.. Also sorry for my english
Cheers
Just a few ideas:
1. Convert image to HSV color space and look only for black and white regions (using inRange function). Blobs which contains only those 2 colors probably will be your informations (but unfortunetely some other things too - barcode, maybe some drawing or logo).
2 You regions should be rectangles, so if the blob is not rectangle - discard it.
3. If founded rectangle is rotated use affineTransform function to align it vertically - here i've explained how to do it. Note that rectangle width and height should stay the same.
4. After using affine transform your rectangle might be rotated by 90, 180 or 270 degrees. In the example you provided on the top there is a black region - it it's true for all you images than finding top is quite easy - just find black rectangle within you region. In other case finding top might be harder - a quick idea, which might be worth testing is to look for black pixels in each white rectangle. In most cases there are aligned to center (not interesting case for us) or to the left - if you find left sied of rectangle, finding top is obvious :) Alternatively you may look for characters which are always on the right side - %, g and mg
If you will have any problems, give us more examples and describe what you have done already - right know it's hard to tell something more.

When i random my object so its overlapping too much [duplicate]

I am looking for a sound algorithm that would randomly place a given number of rectangles of the same size into a bigger rectangle (canvas).
I see two ways to do it:
create an empty array that will contain the rectangles already placed on canvas. start with the empty canvas. in a loop, pick a position at random for a new rectangle to be placed. check if the array has a rectangle that overlaps with the new rectangle. if it does not, put the new rectangle in to the array and repeat the loop. otherwise, pick a new position, and rerun the check again. and so on. This might never terminate (theoretically) I think. I do not like it.
use a grid and place rectangles into the cells randomly. This might still look like a grid placement. I do not like it either.
any better ways to do it? "better" meaning more efficient, or more visually "random" than the grid approach. better in any respect.
Here is a simple heuristic. It will be non-overlapping and random.
Place a rectangle randomly. Then, calculate the intersections of extensions of the the two parallel edges of the first rectangle with the edges of the canvas. You will obtain four convex empty regions. Place other rectangles in these empty regions one-by-one independently and calculate the similar divisions for placements. And try to put the remaining rectangles in empty regions.
You can try different strategies. You can try to place the rectangles close to the corners. Or, you can place them around the center of the regions. We cannot discuss optimality because you introduced randomness.
You might find Quadtrees or R-trees useful for your purpose.
I create internal room-like dungeons using the following method.
1) Scatter N points at random, but not within a few pixels of each other.
2) For each point in turn, expand if possible in all four directions. Cease
expanding if you hit another rectangle.
3) Cease the algorithm when no rooms can expand.
The result is N rectancles with just a few rectangular small spaces.
Code is in the binary image library
https://github.com/MalcolmMcLean/binaryimagelibrary/blob/master/dungeongenerator3.c
#

Drawing a Circular Timer (AndEngine)

I'm using AndEngine, and within that framework, I'd like to make a circular timer graphic. Specifically, I'd like to display the wait period for reuse of an ability. The idea is to dynamically fill the arc as the timer progresses. Something like this:
The java.awt.Graphics object has a fillArc() method that seems perfect for me. In fact, the above graphic was drawn using fillArc(50,5,100,100,75,-40). Great! Now here's the problem:
AndEngine doesn't use Graphics() objects, it uses its own Shape implementation (for OpenGL) and there's no defined "Circle" shape, much less a circle shape with a fillArc() method.
Possible Solutions and Their Respective Problems
Looking around for a solution I ran into "Drawing a circle using Andengine". That Q&A is not of much use to me as the only answer "Indeed, you can't directly draw a circle" offers two alternatives: (1) "Rendering a quad with a circle texture" - this won't work for me as I need to dynamically modify the circle to produce the arcfill; and (2) "Rendering a circle that's actually a circle of connected triangles." Maybe option two would work, but there's no guidance there as to how to do that.
I also ran into "Creating circle in android andengine by box2d?". I suspect someone may be tempted to say, you can simply create a circle like this:
Body circleBody = PhysicsFactory.createCircleBody(pWorld, pSprite,
BodyType.StaticBody, FixtureDef);
That really doesn't help me. I'm not looking to create a 2D physics body of a circle. I'm looking to display one.
Finally, I found this discussion, which is promising. In particular, there's a suggestion:
Use Canvas to draw [it] into a Bitmap, and load that Bitmap as a TextureSource.
Sounds reasonable, although I'm still unclear how to do that.
Update: My Cheating "Solution"
Rather than dwell on this, I decided to cheat (for the moment at least). I made a spritesheet that looks like this:
Rather than actually have the timer display the perfect fillArc(), I just pull the appropriate index of the sprite from the spritesheet based on rounding the proportion done (from 0 to 1) to the appropriate index on the spritesheet. Like this:
public void setTimer(float amount) {
this.setCurrentTileIndex(Math.round(amount * 20));
}
For my purposes, this actually works just fine--I'm using the timers over about 2 seconds, so you really don't see the lack of detail. But maybe I'll get around to replacing this with the "proper" solution if someone posts it. Also, maybe this spritesheet will be useful for someone doing the same thing. Here's the version using transparency instead of a green background. (So it's white on the white background of stackoverflow, but it's there):
There is a third solution that requires a single texture and a custom object. So it's a trade off between your solutions, where one requires a lot of triangles and the other one a texture memory.
You need only one image, i.e. the full circle in your "cheat sequence" above.
Create a custom object consisting of 8 triangles (one 'fully drawn' triangle will represent 45° each).
The progress determines:
How many of the triangles to draw. I.e.:
100% ==> 360° ==> 8 full triangles
50% ==> 180° ==> 4 full triangles
37.5% ==> 135° ==> 3 full triangles
25% ==> 90° ==> 2 full triangles
20% ==> 72° ==> 1 full triangle and one triangle with one vertex moved so that it represents the remaining 27° (== 72° - 45°).
If you ask me this is the coolest solution, since it can be applied to any texture. =)

Android - Puzzle Piece

I'm trying to create a jigsaw puzzle app for Android. I am fairly far into the coding, and I am kind of stuck with one issue.
I need a way to change a Bitmap into a bunch of puzzle pieces. My current code simply cuts the image into rectangles, and it works pretty well, but now I need a way to create more complex piece shapes.
I had a couple of ideas:
Use a separate bitmap file that contains only black and white pixels, and use that to cut up the picture. I thought this was a pretty good plan, until I went to code it. I really had no idea how to do it.
Use a Path object to create the border. This would probably work, except I'm not sure how to keep track of the sides so that the pieces connect with each other.
Any ideas? I'm open to any suggestions.
You can use Path and/or Region to set a clip for your Canvas when drawing a Bitmap.
Take a look at this example. Here are some ways of clipping your drawing to any shape.
You could try making squares or rectangles fitted inside complex figures that can still be pieced toguether, when there's a match, the full rectangle covers the space. Imagine it like a 9 patch, when two sides match, you show the border rectangle.
This is not a explicit solution but I wonder if it would be possible to use bezier curves or paths to create lines along x and y , in conjunction with a parameter(fed with random value) to control the amount of deviation from a straight line and how much in a given distance ie; pixels/ per inch - this would be to create tongues on the pieces. Then use Region to extract the resulting shape at a given side of an intersection. Have the shape object get its center xy coordinate at instantiation and make it so that piece cannot be set if its current coordinate does not match the one it had when it was created.

Detecting billiard balls with OpenCV

I'm making an android app that takes an image of a billiards game in progress and detects the positions of the various balls. The image is taken from someone's phone, so of course I don't have a perfect overhead view of the table. Right now I'm using houghcircles to find the balls, and it's doing an ok job, but it seems to miss a few balls here and there, and then there are the false positives.
My biggest problem right now is, how do I cut down on the false positives found outside the table? I'm using an ROI to cut off the top portion of the image because it's mostly wasted space, but I can't make it any smaller or I risk cutting off portions of the table since it's a trapezoidal shape. My current idea is to overlay the guide that the user sees when taking the picture on top of the image, but the problem with that is that I don't know what the resolution of the their cameras would be, and therefore the overlay might cover up the wrong spots. Ideally I think I would want to use houghlines but when I tried it my app crashed from what I believe was a lack of memory. Any ideas?
Here is a link to the results I'm getting:
http://graphiquest.com/cvhoughcircles.html
Here is my code:
IplImage img = cvLoadImage("/sdcard/DCIM/test/picture"+i+".jpg",1);
IplImage gray = opencv_core.cvCreateImage( opencv_core.cvSize( img.width(), img.height() ), opencv_core.IPL_DEPTH_8U, 1);
cvCvtColor(img, gray, opencv_imgproc.CV_RGB2GRAY );
cvSetImageROI(gray, cvRect(0, (int)(img.height()*.15), (int)img.width(), (int)(img.height()-(img.height()*.20))));
cvSmooth(gray,gray,opencv_imgproc.CV_GAUSSIAN,9,9,2,2);
Pointer circles = CvMemStorage.create();
CvSeq seq = cvHoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2.5d, (double)gray.height()/30, 70d, 100d, 0, 80);
for(int j=0; j<seq.total(); j++){
CvPoint3D32f point = new CvPoint3D32f(cvGetSeqElem(seq, j));
float xyr[] = {point.x(),point.y(),point.z()};
CvPoint center = new CvPoint(Math.round(xyr[0]), Math.round(xyr[1]));
int radius = Math.round(xyr[2]);
cvCircle(gray, center, 3, CvScalar.GREEN, -1, 8, 0);
cvCircle(gray, center, radius, CvScalar.BLUE, 3, 8, 0);
}
String path = "/sdcard/DCIM/test/";
File photo=new File(path, "picture"+i+"_2.jpg");
if (photo.exists())
{
photo.delete();
}
cvSaveImage("/sdcard/DCIM/test/picture"+i+"_2.jpg", gray);
There are some very helpful constraints you could apply. In addition to doing a rectangular region of interest, you should mask your results with the actual trapezoidal shape of the pool table. Use the color information of the image to find the pool table region. You know that the pool table is a solid color. It doesn't have to be green - you can use some histogram techniques in HSV color space to find the most prevalent color in the image, perhaps favoring pixels toward the center. It's very likely to detect the color of the pool table. Select pixels matching this color, perform morphological operations to remove noise, and then you can treat the mask as a contour, and find its convexHull. Fill the hull to remove the holes created by the pool balls.
What I've said so far should suggest a different approach than Hough circles. Hough circles is probably not working too well since the billiard balls are not evenly illuminated. So, another way to find billiard balls is to subtract the pool table color mask from its convexHull. You'll be left with the areas of the table that are obscured by balls.
I've thought about working on this problem, too, since I play pool and snooker.
A few points:
Judging from the Hough circle fits, it looks like you're not filtering the edge points, or your threshold for edge strength isn't high enough. Are you simply using a binary indicator for edge points, or are you selecting edge points based on edge strength?
Can you work in RGB space? That'd help with detecting the table bed, the rails, and also in identifying the balls. A blue blob on the table bed could be the 2-ball, the 10-ball, or maybe a hunk of chalk.
In your parameter space, you should be able to limit the search for circles of a very limited radius. This would be helped in part if...
Detect the table surface and the rails. A Stroke Width Transform could help you find the rails, especially if you search in a color plane (green) in which the rails will have high contrast. You can also use the six pockets (or at least three pockets) to help identify the pose (position and orientation) of the table.
Once the rails are detected, you can use an affine transform to correct for perspective distortion. You'll need to do this anyway to place the balls with any sort of accuracy, especially if you want the ball placement to satisfy a serious pool player such as someone who plays One Pocket or Straight Pool. Once you have the affine transform, you can set fairly tight tolerances for radius in your Hough parameter space.
Once you've detected the table bed, you could perform an initial segmentation (that is, region labeling or blob finding) and search only for blobs of a certain area and roundness.
A strong, even, diffuse overhead light could help eliminate shadows.
You can help filter edge points by accepting (or at least favoring) edge points that have gradients that are pointed towards other edge points with parallel gradients. If a local collection of edge point pairs "point" at each other via their edge gradients, then they are good candidates for detection.
Once you've detected a candidate ball, perform further processing to accept/reject. A ball should be a relatively uniform hue (cue ball, 1 - 8, or a stripe viewed from the proper angle), or it should have a detectable color stripe and white. The ball surface will not be highly textured like the wood grain of the table.
Have an option that the user take two pictures from slightly different angles. You then have two chances to find balls, and could conceivably solve the correspondence problem of matching the tables and balls in the two images to help locate the balls in the 2D space of the table bed.
Consider having a second algorithm such as normalized cross-correlation (simple template matching) to help identify balls or at least likely ball locations.
Insist that the center point of the image be located somewhere within the table bed. This can help you identifying the positions of the rails since you can then search radially outward for the edges of the rails, and once four (or even just three) rails are found you can reject edge points at radial distances beyond them.
Good luck! It's a fun problem.
EDIT:
I was reading another StackOverflow post and read about this paper. The paper which will give you a much more thorough introduction to the technique I suggested to filter edge points (item 8).
"Fast Circle Detection Using Gradient Pair Vectors" by Rad, Faez, and Qaragozlou
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.121.9956
I haven't implemented their algorithm myself yet, but it looks promising. Here's the post where the paper was mentioned:
Three Dimensional Hough Space

Categories

Resources