C++/OpenCV find objects on an image - c++

I have to find a couple of objects on an image. For example find all black pawns on a chessboard:
How can I achieve that,using OpenCV ?
I think about cv::matchTemplate, however I'm not sure how would it proceed with different pawn backgrounds. I'm also not sure if I can easily get all matchings in that way.

Start with corner detection (well known shi tomasi method, or smt like line detection and intersection, since it should work better for your case) and collection of 64 subsamples of image -the squares. If the board is ideal - pure birds eye view -and you know the size (8x8 here), then just crop it into WxH pieces. You should save these samples with their coordinates (b6, h1 etc).
For every square, a low pass filter smt like gaussian, then otsu threshold and contour detection should give you at most one big contour. If there is none, that square is empty.
You can try to get the contours from the initial state of the board, and name them. This is your training data. Since pieces are not gonna differ much; 1 sample is enough :) Save a "white pawn"s (any square from 2nd row initially) area, hu moments and color (mean rgb value is OK). Then save a "black pawn". Then "white queen" and "black queen" (d4 d8). Do that area, moment, color table for all pieces.
Later, for any state of the board, you can try to match hu moments, color and area of your contour -output of those squares, using your identification table. Of course some statistical method like knn could help you there. You can also utilize matchShapes method.
At last you identify your contour smt like black knight, red checker piece, etc.

Related

Biggest Rectangle within one color

I struggle to find a solution to the following problem :
I used opencv to mark all connected white pixels with a unique label.
Now i got a group of those elements.
Those objects often are 90% rectangular but most of the time contain some extra lines and stuff.
Im searching for a algorithm which does thr following :
-get biggest Rectangle out of image(within the same label)
- fast performance
-maybe even filter, larget rectangle which contains at least xx% Pixels with the same label
Maybe someone can help me
Thanks a lot
Edit: Example Pictures(in this case fo licence plate location):
my desired output of the algorithm would be the rectangle of the plate(and of curse all other rectangles in the image, im gonna filter them later)
Important the rectangles may be rotated !
My suggestion
make sure to fill small holes either by blob analysis or mathematical morphology;
compute the distance map in the white areas;
binarize the distance map with a threshold equal to the half plate height.
The rectangles will appear as line segments long as the plate width minus the plate height. You may locate them by fitting rotated rectangular bounding boxes; they must have a large aspect ratio.

Infrared images segmentation using OpenCV

Let's say I have a series of infrared pictures and the task is to isolate human body from other objects in the picture. The problem is a noise from other relatively hot objects like lamps and their 'hot' shades.
Simple thresholding methods like binary and/or Otsu didn't give good results on difficult (noisy) pictures, so I've decided to do it manually.
Here are some samples
The results are not terrible, but I think they can be improved. Here I simple select pixels by hue value of HSV. More or less, hot pixels are located in this area: hue < 50, hue > 300. My main concern here is these pink pixels which sometimes are noise from lamps but sometimes are parts of human body, so I can't simply discard them without causing significant damage to the results: e.g. on the left picture this will 'destroy' half of the left hand and so on.
As the last resort I could use some strong filtering and erosion but I still believe there's a way somehow to told to OpenCV: hey, I don't need these pink areas unless they are part of a large hot cluster.
Any ideas, keywords, techniques, good articles? Thank in advance
FIR data is presumably monotonically proportional (if not linear) to temperature, and this should yield a grayscale image.
Your examples are colorized with a color map - the color only conveys a single channel of actual information. It would be best if you could work directly on the grayscale image (maybe remap the images to grayscale).
Then, see if you can linearize the images to an actual temperature scale such that the pixel value represents the temperature. Once you do this you can should be able to clamp your image to the temperature range that you expect a person to appear in. Check the datasheets of your camera/imager for the conversion formula.

How can I detect if there is a piece on chess square or not?

I have to detect a chess board and I do that as shown in this picture:
I divided this image in 64 sub-images which represent the black and white chess squares, like:
How can I check whether these sub-images (each square) contains a chess piece?
First you need to refine your squares detection, because you have some white region in the black and vice-versa. To do this quickly you can just crop a smaller ROI in the center of the square, assuming most of the piece will be in the center.
For the actual detection there are all kinds of simple options, which I guess will work perfectly fine in your case. Don't need to go to sophisticated feature detection and machine learning.
Options:
If you know the color of the square, use some threshold to find the piece.
You can look on the standard deviation of the gray level in the square. Without a piece it would be quite low, so you could use some threshold here.
You can do background subtraction with an empty square.
Either way, there will be some noise, so you will have to play with it a bit to find the best threshold/parameters.
Most of the time it is also better to do some pre-processing blur to get smoother results.
There are a lot of things that you need to consider:
Is necessary to have that perspective of the chess?. A top perspective can help you to make your process easier, by doing this you are avoiding an invasion of a piece in other square.
then you can check if there is a piece of chess in a square by checking the histogram of it. If the square doesn't have a piece you can appreciate a single peak in the curve, if there is a piece in that square you will appreciate more than one peak. You can use a threshold in the histogram to find if there is a single peak or not (by finding the max points in the histogram)

Get all the image pixels with certain pixel values with K-nearest neighbor

I want to obtain all the pixels in an image with pixel values closest to certain pixels in an image. For example, I have an image which has a view of ocean (deep blue), clear sky (light blue), beach, and houses. I want to find all the pixels that are closest to deep blue in order to classify it as water. My problem is sky also gets classified as water. Someone suggested to use K nearest neighbor algorithm, but there are few examples online that use old C style. Can anyone provide me example on K-NN using OpenCv C++?
"Classify it as water" and "obtain all the pixels in an image with pixel values closest to certain pixels in an image" are not the same task. Color properties is not enough for classification you described. You will always have a number of same colored points on water and sky. So you have to use more detailed analysis. For instance if you know your object is self-connected you can use something like water-shred to fill this region and ignore distant and not connected regions in sky of the same color as water (suppose you will successfully detect by edge-detector horizon-line which split water and sky).
Also you can use more information about object you want to select like structure: calculate its entropy etc. Then you can use also K-nearest neighbor algorithm in multi-dimensional space where 1st 3 dimensions is color, 4th - entropy etc. But you can also simply check every image pixel if it is in epsilon-neighborhood of selected pixels area (I mean color-entropy 4D-space, 3 dimension from color + 1 dimension from entropy) using simple Euclidean metric -- it is pretty fast and could be accelerated by GPU .

Detect ball/circle in OpenCV (C++)

I am trying to detect a ball in an filtered image.
In this image I've already removed the stuff that can't be part of the object.
Of course I tried the HoughCircle function, but I did not get the expected output.
Either it didn't find the ball or there were too many circles detected.
The problem is that the ball isn't completly round.
Screenshots:
I had the idea that it could work, if I identify single objects, calculate their center and check whether the radius is about the same in different directions.
But it would be nice if it detect the ball also if he isn't completely visible.
And with that method I can't detect semi-circles or something like that.
EDIT: These images are from a video stream (real time).
What other method could I try?
Looks like you've used difference imaging or something similar to obtain the images you have..? Instead of looking for circles, look for a more generic loop. Suggestions:
Separate all connected components.
For every connected component -
Walk around the contour and collect all contour pixels in a list
Suggestion 1: Use least squares to fit an ellipse to the contour points
Suggestion 2: Study the curvature of every contour pixel and check if it fits a circle or ellipse. This check may be done by computing a histogram of edge orientations for the contour pixels, or by checking the gradients of orienations from contour pixel to contour pixel. In the second case, for a circle or ellipse, the gradients should be almost uniform (ask me if this isn't very clear).
Apply constraints on perimeter, area, lengths of major and minor axes, etc. of the ellipse or loop. Collect these properties as features.
You can either use hard-coded heuristics/thresholds to classify a set of features as ball/non-ball, or use a machine learning algorithm. I would first keep it simple and simply use thresholds obtained after studying some images.
Hope this helps.