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...
Related
I couldn't find any satisfying answer on that topic. I want to make a program that will get snapshots from camera above the pool table and detect balls. I am using OpenCV and Java. My algorithm now is basically:
blurring image -> converting RGB to HSV -> splitting into 3 planes -> using Canny() on H plane -> using HoughCircles() method to detect balls
This algorithm detects balls quite well, it has problem with two balls only (green and blue, because background of the table is green). But I want to go one step further and:
Detect if the ball belongs to stripes or solids
Set an ID of every ball, stripes would have for example 1-7 and solids 8-14, every ball would have unique ID that doesn't change during the game
Do you have any idea how to implement task #1? My idea is to use inRange() function, but then I'd have to prepare a mask for every ball that detects that one ball in specified range of colors, and do this detection for every ball, am I right? Thanks for sharing your opinions.
#Edit: Here I give you some samples of how my algorithm works. I changed some parameters because I wanted to detect everything, and now it works worse, but it still works with quite nice accuracy. I`ll give you three samples of original image from camera, image where I detect balls (undistorted, with some filters) and image with detected balls.
Recommendation:
If you can mask out the pixels corresponding to a ball, the following method should work to differentiate striped/solid balls based on their associated pixels:
Desaturate the ball pixels and threshold them at some brightness p.
Count the number of white pixels and total pixels within the ball area.
Threshold on counts: if the proportion of white pixels is greater than some threshold q, classify it as a striped ball. Otherwise, it's a solid ball.
(The idea being that the stripes are white, and always at least partially visible, so striped balls will have a higher proportion of white pixels).
Sample Testing:
Here's an example of this applied (by hand, with p = 0.7) to some of the balls in the unrectified image, with final % white pixels on the right.
It looks like a classification threshold of q = 0.1 (minimum 10% white pixels to be a striped ball) will distinguish the two groups, although it would be ideal to tune the thresholds based on more data.
If you run into issues with shadowed balls using this method, you also can try rescaling each ball's brightnesses before thresholding (so that the brightnesses span the full range 0, 1), which should make the method less dependent on the absolute brightness.
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...
I'm trying to detect rectangles in a image, I know this is possible with OpenCv but I was thinking of using ImageMagick. The question is, is it possible to do it with ImageMagick? I was looking to find a equivalent findContours function from OpenCV in ImageMagick but I couldn't find one?
Here's a not fully robust version that achieves what I have need for simply connected regions. It plays on the fact that there are no holes for the regions the contours bound and that no region makes contact with the coordinate 0,0. Both are not likely in my application so I'm able to exploit these facts to establish the background. I can also exploit that I know in advance what the color of my contour is, which I've indicated with #ContourColor
convert inputImage.jpg -fill black +opaque #ContourColor
-fill blue -draw "color 0,0 floodfill"
-fill #ContourColor -opaque black
-fill white -opaque #ContourColor
-fill black -opaque blue
outputImage.jpg
Here's the breakdown of each step...
Fill everything not ContourColor as black
Fill background as blue, assuming no simply connected object touches top left pixel 0,0
Fill all black interiors as ContourColor to fill contours
Replace ContourColor for White to establish foreground
Replace blue background as black to establish background
It would be very useful for ImageMagick to implement the same contour functionality as OpenCV, but I'm in the same boat as you where I'm just looking for a simple tool to tease out some regions that I happen to be hand drawing and wish to make use of in some image processing regression tests. I don't want to write a full blown application to make these segmentation comparisons and am hoping I can get by scripting some ImageMagick magic!
Contours of this image will be double lines due to the thickness of the outline and text. For example to get the contours (outline) of the green box, use
convert HetI7.jpg -fuzz 20% -fill white +opaque green1 -morphology edgeout diamond:1 -negate green_outline.png
But perhaps you just want the green box and not its outline.
convert HetI7.jpg -fuzz 40% -fill white +opaque green1 green_region.png
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!
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.