Detecting (and locating) predefined shapes in image in Java - java

Given an image and a set of predefined unique shapes with a certain colour (e.g. red triangle, green circle, green triangle, yellow square, ...). The image contains some of these shapes at random locations. I have the predefined shapes available as an image-file for each shape if needed.
How can I detect/recognise all of these shapes and return their location in some way, in Java?
OpenCV seems to be a common solution for Python, but I can't find any helpful example/tutorial for Java. I really don't know where to start. Hints/examples much appreciated!

Related

Java and OpenCV color detection

I'm working on a project at school, which basically is: writing an application to make a drone fly autonomously, and through scanning QR-codes hung up on walls, be able to navigate through a room in order to complete a certain task.
What I am currently working on, is for the drone to detect cardboard boxes (working as obstacles). These boxes are white, and have a blue circle on them. How I'm planning to solve this, is by scanning the frame for colors and squares:
If the drone detects a square, check if it's white. If it's white, check if it contains a blue circle. If it does, I can say that it most likely is a cardboard box.
This is what the box looks like:
If anyone would be able to provide some pointers as to how I can start working on the color detection, I would be very happy!
PS: I haven't provided any code, since I don't really know what to provide. I would be more than happy to provide some if needed
UPDATE: for anyone stuck at the same problem as I, a fellow student provided an excellent link for my exact situation:
http://opencv-java-tutorials.readthedocs.io/en/latest/08-object-detection.html
I would go from a different angle to do this by detecting the blue circle first.
Detect base colors
see RGB value base color name
Select all blue pixels neighboring white or gray-ish ones
As your circlehas black border then you have to select all blue pixels near white,gray,black... just to be sure. This is the result (Green are selected pixels):
another (more robust) possibility is to select all black pixels neighboring white and blue at the same time.
do a connected components analysis
so merge all connected pixels into polylines
For each polyline decide if it is circle/ellipse/oval
that can be done by investigating angle between line segments. If has sharp spikes then sharp edges are present and it is not an oval. If the circumference is too far from circle/elipse/oval computed from its bounding box then it is not oval but some more complicated curvature.
For each oval decide if it is filled with blue
so just flood fill mask of the oval circumference and compare how many pixels are int the original image blue against those that are not. if the ratio is closer to 100% blue then it is filled blue oval shape....
As your marker has also some features inside you can compute the ratio of all base colors inside it to more accurately detect the marker.
Look at Algorithms: Ellipse matching for some additional ideas.
now you can similarly check if the background is white/gray-ish
There are a lot of other possible approaches like OCR and character similarity or based on FFT/DCT, Hough transform for circles... also you are not bound only to geometric properties comparation instead you can compare histograms...

Java - split image into jigsaw pieces

I need to create a jigsaw puzzle game. I've already done this in the past using AndEngine, however I've only cut texture into rectangles. Now I need to cut it into proper jigsaw pieces. How can I do that?
Cut the texture into rectangles but for every rectangle take extra space. So you would have a lot of rectangles which overlap each other.
Then you need to have some set of patterns for jigsaw edges (black and white images or you can call it a mask) and generate a mask for every rectangle using those patterns.
The algorithm would be:
create a mask with a size of rectangle and initialise it with white color.
Then choose edge pattens based on rectangle-neighbors if they are initialised or choose edges randomly if neighbors are not yet initialize.
After you chose the patterns, draw them on a mask for every side. So in the end you would have a mask with a shape of a jigsaw piece. white color = visible, black color - transparent.
Then apply the mask to the rectangle when you draw it.
And bare in mind that you don't stack these rectangles based on their actual size, but stack in a way that they would overlay each other...
P.S. I hope you understood what I was trying to say. Sorry, English is not my native language...

Rendering a triangular face in 3d space

Let's say I have a triangular face in 3d space, and I have the 3d coordinates of each vertex of this triangle, and would also have other information about the triangle(angles, lengths of sides, etc.). In Java, if I have the viewing screen and its information, how can I draw that plane, without using libraries like LWJGL, to that image, assuming I can properly project, accounting for perspective, any 3d point to that 2d image.
Would the best course of action just be to run a loop that draws each point on the plain to a point on the image(i.e. setting the corresponding pixel), which will most likely set the same pixel multiple times? If I'd do this, what would be the best way to identify each point in an oblique triangle, or a triangle that doesn't line up nicely with the axes?
tl;dr: I have a triangular face in 3d space, a "camera" looking at the face, and an image in which I can set each pixel. Using no GL libraries, what's the best way to project and draw that face onto the image?
Projection :
won't detail as you seems to know it
Drawing a line
you can look at Bresenham algorithm if you wanna start with the basics
(hardwared in recent graphics card)
Filling
you can fill between left and right borders of the triangle while you use Bresenham on both (you could use a floodfill algorithm starting ... i don't know, maybe at the projection of the center of the triangle)
Your best bet is to check out the g.fillPolygon() function for Java. It allows you to draw polygons with as many sides as possible and theres also g.drawPolygon() if you don't want it solid. Then you can just do some simple maths for the points. Such as each point is basically it's x and y except if the polygon is further away the points move closer to the center of the polygon and if the polygon is closer they move further away from the center of the polygon.
A second idea could be using some sort of array to store pixels and then researching line drawing algorithms and drawing lines then putting all the line data in another array and using some sort of flood-fill. Then whilst it's in that array you could try and do some weird stuff to the pixels if you wanted textures or something.

Detecting when an image intersects a certain color?

I am 11 years old, and I program with Java, HTML, and CSS. Well what I have is a game, and its a Minecraft 2D Platformer.
Well I have some water to the side, and what I want to do is when the player intersects that water, I want it to slow down. Here is a example if there was a method to do this, in case you still don't understand my goal.
if (player.intersectsColor("0026FF"))
playerSpeed = 2;
else
playerSpeed = 3;
I suggest you represent the water not by its color but by its location. That way you can check whether the player is in a "tile" representing water, and adjust the speed accordingly.
This you can do with simple comparison on the x/y coordinates (adjusted for the size of the "tile"/"player")
If you don't have nice meshy tiles, but curves/polygons, you will need to read up on geometry and how to calculate (possibly curved) line intersection. The exact algorithm will depend on the curve used.
The reason I discourage you from using the color itself for the intersection many twofold:
"Intersecting" on a single color limits your ability to dynamically color the terrain/objects later
You cannot have two different terrain.object type with the same color
Having the color (e.g. brown) of the terrain/object does not tell you which blue terrain/object the player ran into (e.g. is it the first or the second chest?)
If you really want to represent the terrain with colors, you can translate the players in-game coordinates to screen coordinates and see what color pixel you have at that coordinate on the screen (before the player was rendered on the scene), but this is messy.

Detect lines and its curve hand drawn by Graphics2d in a java draw application

I'm making a music application that enables you to freedraw lines from specified colors and then a trackbar would pass on top of it and should detect the curves and color to output sound and modified pitch etc depending on the curves.
What I'm looking for is help on detecting the lines and curves. They are drawn in a Label as a BUfferedImage. The following is a screenshot:
The Black line I drew to represent the trackbar, but infact it would be a Rectangle drawn by drawRect or it could be a imagepanel, depends on the way you detect lines.
My question:
How could I detect the yellow, green, etc lines and its curve and handle that data? If I get that data I could easily modify gain and pitch for each assign sound for each color. Thanks!
You want to store the coordinates of the user's drawing motions at the very least. You could store these as points or convert them into representations of line segments and/or curves depending on your requirements. Of course, store the stroke, color and anything you want as part of this model.
To accomplish this, I think the path of least resistance would probably have you utilizing java.awt.Shape and everything in java.awt.geom. Specifically, I think you would want to represent each user-drawn element as one or more Path2D and/or Area objects in response to user drawing motions. Then, have your GUI render these models on your custom Component.
Path2D would store the movements as lines and curves accessible through a PathIterator. Given a trackbar represented by a Rectangle2D, you can use the various methods available for comparing and combining geometries--namely the Shape interface's intersects(Rectangle2D) here. If a geometry model intersects your trackbar, you could then iterate through the path components until you find the actual sub-segment that is intersecting. This gets you the local slope.

Categories