Counting foreground objects in a binary image - visual-c++

I have an image sequence (video). I would like to count the number of objects in the image sequence. But the main objective is to count them once, meaning not just in each and every frame, since an object may exist in for several frames. My idea is to count the objects as they exit the screen, because of less occlusions. I am thinking of doing this by scanning the bottom part of the image for non zero pixels.
I have a CV_FILLED binary image (from rectangle function) where I want to do the scanning, then create an instance on an object if abject is found. But this scanning will not be scanning each and every pixel along the horizontal line, just certain sections.
Like we could do it over ranges, say certain columns, then skip by a margin.
A sample binary image I have is attached . This is an image obtained from the feed. I do not want to count only the objects in this image, but also those that are still coming.
A full picture of detected objects is attached here.Your guidance or constructive criticism is welcome
* I do not want to use CVBlob

If you don't want to use cvBlobLib, you could use the contour detection that is part of OpenCV.
There is a tutorial on the website.
The doc for the method is here. Your image seem pretty simple, but if you get blobs with occlusions and so you want to look at the CV_RETR_EXTERNAL constant to get only the outer contours.
That is what I usualy use, even though it needs a bit more work to use the results of the method.
Hope this helps.

If the squares do not overlap at the bottom, I suggest the following:
scan the very bottom row of the image and identify those connected pixels which are white. Each white line will correspond to one square. Save the center of the white line segment and its length. In the next frame, do the same and associate the corresponding line segments to the previous (same length and center very close). When you cannot find a corresponding line segment anymore, the square has moved out of the image which means you can increase your squares counter by one. Note that line segments at the right and left ends of the line will have decreasing length with every frame.

Thx guys. I managed to solve this already. I used small ROIs along the paths of the squares, and found countNonZero() within the ROI.
I kept on checking with boolean variables to see if the ROI still had the white pixels. If not, incremented counter. Worked well, and I was able to count.
Thx for your input...

Related

Counting fishes on an image

I want to build a script that can count and box fishes in a given image with the assumption that the image will always contain fishes (any number) and no other animals.
My current approach is just to count the number of contours detected in an image. I use canny edge detection with dilation and erosion. I also discard contours that are too small, treating them as noise.
This approach seems to be working fine if the fishes are nicely separated. But once they are intersecting, or covering each other, things start to get messy.
Currently, I am just using images from google.
What other approach can I use for this problem? Still a newbie in image processing.
Thank you so much!
What other approach can I use for this problem?
You can try to detect just a particular feature of the fish, such as an eye, mouth, or fin. You can try to detect whole fish, and also count particular features as above; if the numbers don't match you can deduce that you've found some partial fish.

Extracting part of a 2D image in OpenCV

enter image description here
My goal is to take the image above and "open" it along the center so that the 9 black doublets are in a straight line rather than in a circle. I have tried using the cv2.toPolar() function in OpenCV but the image is quite distorted, as can be seen below:
enter image description here
I am attempting to try a different approach now. From the center, I would like to access each of the doublet individually, like a pizza slice, and place them side by side
Initially I was thinking of slicing each doublet using two lines from the center of the image to the mid point between the doublets on either side.
My question is: how can I draw contours from the center of the image to the edge of the image, passing through the mid point between any two doublet. If I can draw one, I know that the angle between any two such consecutive contour is 40 degrees.
Any help is greatly appreciated!
I noted a few problems here:
The toPolar() conversion might have been around the center of the image file, but it is not the center of the object. This causes part of the distortion. If you share your code, I could try playing with the code and improving it.
2.The object is somewhat elliptical, not circular. This means you will still have a wave after correcting the above problem.
If you don't mind a semi-automatic solution, you could use OpenCV mouse events to specify the first line and let the program use the 40 degree angle to calculate the rest.

How to make a custom textiled background

<------This is an image I made in Photoshop...
It's basically a 160 x 160 box of white with a texture applied.
Below is what it looks like with "background-repeat" in the CSS. I was hoping it'd balance out. Is there a certain percentage the textile has to be at, or size of the original box? For it to be a perfect repeatable texture?
Im trying to do this myself, since I cant find grid patterns that fit the style.
Question: Whats the trick on making textures in Photoshop, that appear as balanced whole backgrounds when repeated?
If you look at the below image where it's in effect, on the very basic start of what Im working on, you can notice it doesnt quite fit together.
Any and all help greatly appreciated. Thanks in advance.
If you want that background for a webpage is better the use of repeating-linear-gradient. It is very easy of implement, less assets to download and it is supported by major browsers.
Look in the top left corner of your image. You'll note that the dark line starts at roughly 4-5 pixels from the top. Then look at the top right corner, and you'll note that the top line starts at just perhaps 2px from the top.
When this image is repeated twice side by side, there will be a disconnect. Just crop the image and shave off the two or three pixels until your lines connect. Repeat by cropping the bottom of the image for vertical alignment.
If you want to do this experimentally, increase the size of your canvas, and copy the pattern into a new 160x160 layer. Place them side by side, and then move the layers one pixel at a time so that they overlap. Where the overlap aligns is where you should crop the image.

Turn an image into lines and circles

I need to be able to turn a black and white image into series of lines (start, end points) and circles (start point, radius). I have a "pen width" that's constant.
(I'm working with a screen that can only work with this kind of graphics).
Problem is, I don't want to over complicate things - I could represent any image with loads of small lines, but it would take a lot of time to draw, so I basically want to "approximate" the image using those lines and circles.
I've tried several approaches (guessing lines, working area by area, etc) but none had any reasonable results without using a lot of lines and circles.
Any idea on how to approach this problem?
Thanks in advance!
You don't specify what language you are working in here but I'd suggest OpenCV if possible. If not, then most decent CV libraries ought to support the features that I'm about to describe here.
You don't say if the input is already composed of simple shapes ( lines and polygons) or not. Assuming that it's not, i.e. it's a photo or frame from a video for example, you'll need to do some edge extraction to find the lines that you are going to model. Use a Canny or other edge detector to convert the image into a series of lines.
I suggest that you then extract Circles as they are the richest feature that you can model directly. You should consider using a Hough Circle transform to locate circles in your edge image. Once you've located them you need to remove them from the edge image (to avoid duplicating them in the line processing section below).
Now, for each pixel in the edge image that's 'on' you want to find the longest line segment that it's a part of. There are a number of algorithms for doing this, simplest would be Probabilistic Hough Transform (also available in openCV) to extract line segments which will give you control over the minimum length, allowed gaps etc. You may also want to examine alternatives like LSWMS which has OpenCV source code freely available.
Once you have extracted the lines and circles you can plot them into a new image or save the coordinates for your output device.

Preventing pixelshader overdraw for a single ERG

Background
Using gluTess to build a triangle list in Direct3D9 from a GDI+ DrawString(..) path:
A pixel shader (v3.0) is then used to fill in the shape. When painting with opaque values, everything looks fine:
The problem
At certain font sizes, if the color has an alpha component (ie Argb #55FFFFFF) we begin to see these nasty tessellation artifacts where triangles may overlap ever so slightly:
At larger font sizes the problem is sometimes not present:
Using Intel's excellent GPA Frame Analyzer Pixel History tool, we can see in areas where the artifacts occur, the pixel has been "touched" 3 times from the single Erg.
I'm trying to figure out how I can stop my pixel shader from touching the same pixel more than once.
Other solutions relating to overdraw prevention seem to be all about zbuffer strategies, however this problem is more to do with painting of a single 2D triangle list within a single pixel shader pass.
I'm at a bit of a loss trying to come up with a solution on this one. I was hoping that HLSL might have some sort of "touch each pixel only once" flag, but I've been unable to find anything like that. The closest I've found was to set the BLENDOP to MAX instead of ADD. But the output is not correct when blending over other colors in the scene.
I also have SRCBLEND = ONE, DSTBLEND = INVSRCALPHA. The only combination of flags which produce correct output (albeit with overdraw artifacts.)
I have played with SEPARATEALPHABLENDENABLE in the GPA frame analyzer, which sounded like almost exactly what I need here -- set blending to MAX but only on the "alpha" channel, however from what I can determine, that setting (and corresponding BLENDOPALPHA) affects nothing at all.
One final thing I thought of was to bake text as opaque onto a texture, and then repaint that texture into the scene with the appropriate alpha value applied, however this doesn't actually work in this project because I also support gradient brushes, where stop values may contain alpha, meaning either the artifacts would still be seen, or the final output just plain wrong if we stripped the alpha away from the stop values prior to baking to a texture. Also the whole endeavor would be hideously expensive.
Any hints or pointers would be appreciated. Thanks for reading.
The problem you're seeing shouldn't happen.
If two of your triangles are overlapping it's because you've placed the vertices in such a way that when the adjacent triangles are drawn, they overlap. What's probably happening is that these two adjacent triangles share two vertices, but each triangle has its own copy of each vertex that's been calculated to be in a very, very slightly different position.
The solution to the problem isn't to try and make the pixel shader touch the pixel only once it's to use an index buffer (if you aren't already) and have the shared vertices between each triangle actually share the same vertex and not use one that's ever-so-slightly not in the same place as the one used by the adjacent triangle.
If you aren't in control of the tessellation algorithm being used you may have to run a pass over the vertex buffer after its been generated to detect and merge vertices that are within some very small tolerance of one another. Even without an index buffer, a naive solution would be this:
For each vertex in the vertex buffer, compare its position to every other vertex in the rest of the vertex buffer.
If two vertices are within some small tolerance of another, replace the second vertex's position with the position of the one you are comparing it against.
This should have the effect of pairing up the positions of two vertices if they are close enough that you deem them to be the same.
You now shouldn't have any problem with overlapping triangles. In everyday rendering two triangles share edges with each other all the time and you won't ever get the effect where they appear to every-so-slightly overlap. The hardware guarantees that a sample point is either on one side of the line or the other, but never both at the same time, no matter how close the point is to the line (even if it's mathematically on the line, it still fails on one side or the other).

Resources