finding image silhouette using openCV - c++

as i want to track motion of an object, i require silhouette of sequence of images.
does anybody know , how to do this?
Silhouette mask is a binary image that has non-zero pixels where the motion occurs

You can use the technique of background subtraction. Here are two ways of doing it.
Subtract the previous frame from the current frame. Only pixels in both frames that haven't changed will result in zero. See cvSub, cvAbsDiff.
Maintain a running average of the video frames. See the function cvRunningAvg in the Motion Analysis and Object Tracking section of the OpenCV docs. For each new frame, subtract the running average from the current frame. When you're done, update the running average with the current frame.
After using one of the methods above, you could segment the resulting difference image using cvThreshold or cvAdaptiveThreshold. This will result in a binary image, ideally with zero where the image was static, and 1 or 255 where motion was present.
Though you didn't mention this in your question, you can then proceed to calculate the contour of the binary image. There's cvFindContours for that.

Have a look at this: Tracking colored objects in OpenCV

Related

OpenCV: Detecting seizure-inducing lights in a video?

I have been working on an algorithm which can detect seizure-inducing strobe lights in a video.
Currently, my code returns virtually every frame as capable of causing a seizure (3Hz flashes).
My code calculates the relative luminance of each pixel and sees how many times the luminance goes up then down, etc. or down then up, etc. by more than 10% within any given second.
Is there any way to do this without comparing each individual pixel within a second of each other and that only returns the correct frames.
An example of what I am trying to emulate: https://trace.umd.edu/peat
The common approach to solving this type of problems is to convert the frames to grayscale and then construct a cube containing frames from a 1 to 3 seconds time interval. From this cube, you can extract the time-varying characteristics of either individual pixels (noisy), or blocks (recommended). The resulting 1D curves can first be observed manually to see if they actually show the 3Hz variation that you are looking for (sometimes, these variations are either lost or distorted because of the camera's auto exposure settings). If you can see it, they you should be able to use FFT to isolate and detect it automatically.
Convert the image to grayscale. Break the image up into blocks, maybe 16x16 or 64x64 or larger (experiment to see what works). Take the average luminance of each block over a minimum of 2/3 seconds. Create a wave of luminance over time. Do an fft on this wave and look for a minimum energy threshold around 3Hz.

Dilation Gradient w/ different ROI's (blob optimization) OPENCV

I'm working on a dilation problem in c++ with opencv. I've captured videoframes of a car park and in order to obtain the best blobs I came up with this.
Erosion (5x5 kernel rectangular), 3 iterations
Dilation GRADIENT (think of it like a color gradient along the y-axis)
So what did I do to get this working? First I needed to know 2 points (x,y) and 2 good dilate kernelsizes at those points. With this information one can inter and extrapolate those values over the whole image. So I calculated ROI's (size and dilation kernelsize) from those parameters. So each ROI has its own predefined kernelsize used for dilation. Note that there isn't any space between two consecutive ROI's (opencv rectangles). Everything is working fine, but there are two side effects:
Buldges on the sides of the blobs. The black line is de border of the ROI!
buldges picture
Blobs which are 'cut off' from the main blob. These aren't actually cut off but the ROI under the one of the blob above dilates (gets pixel information from the above ROI, I think) into blobs who are seperated. It should be one massive blob. blob who shoudn't be there picture
I've tried everything on changing the ROI sizes and left some space between them but the disadvantage is that the blob between 2 seperated ROI's is not dilated.
So my questions are:
What causes those side effects exactly?
What do I have to do to make them go away?
EDIT
So I found my solution: when you call the opencv dilate function, one needs to be sure if the same cv::Mat can be used as destination image. If not you'll be using parts of the original and new image. So all I had to do was including a destination cv::Mat.
This doesn't answer your first question (What causes those side effects for sure), but to make them go away, you can do some variant of the following, assuming the ROI parameters are discrete and not continuous (as seems to be the case).
You can compute the dilation for the entire image using every possible kernel size. Then, after all of those binary images are computed, you can combine them together taking the correct samples from the correct image to get the desired output image. This absolutely will waste a good deal of time, but it should work with no artifacts.
Once you've confirmed that the results you've gotten above (which are pretty much guaranteed to be of as-good-as-possible quality) you can start trying to optimize. One thing I'd try is expanding each of the ROI sizes for computing the dilation by the size of the kernel size. This might get around artifacts that can arise from strange boundary conditions.
This leads to my guess as to what causes the artifacts in the first place: Whenever you take a finite image and run a convolution (or morphological operator) you need to choose what you'll do with the edge pixels. Normally, accessing the pixel at (-4, -1) is meaningless, but to perform the operator you'll have to if your kernel overlaps with it. If OpenCV is doing this edge padding for your subregions, it very easily could give you the artifacts you're seeing.
Hope this helps!

detecting motion on opencv c++ (moving camera)

I'm doing a project for the university and I'm working with OpenCV (that is really awesome).
Now my problem is:
I have a video (.avi) and I have detected all the information I want to know about the blobs that suddenly appear in the RGB range between red and yellow. After I have realized a matrix that saves all the information about the pixel values, finally I create an image in the scale of red that represents the median pixel values.
The real problem is that the video is not static and the camera moves (not too much but it moves).
Can I calculate the x and y coordinates of the camera motion so I could shift the value of the matrix?
Who cares about your English? Till we understand your problem :) What you could really do is to give a shot at KLT motion detection that is implemented in OpenCV. Here is a link to KLT also known as optical flow If you can filter down the motion vectors limited to the blobs you can certainly get hold of the object you want to track. Even better to give KLT the objects initial coordinates/area to track. Have you checked OpenCV blobs library to get hold of the blobs? Here is the link

Difference between pixel based and frame based methods

I am working on video frames using OpenCV. My question might be low leveled, but I want to clarify it first.
There are plenty of pixel based methods available in openCV, but can I change them into frame based ones?
To me, it is similar, since the whole frame is also stored in one matrix, and I will read that matrix from the beginning to end to handle it. So for instance for finding average value, the only thing I should change is find the total average of whole pixels for one frame.
But for one pixel, see several frames and decide that pixel's average based on them. But when it comes to build models like GMM, I cannot differentiate it.
Could someone help explain it clearly?
Can I use or change openCV's GMM for global usage?
I think this is a good definition for the problem, though you are working with pixels.
Pixel-based methods: The information of the pixel(x,y) in the resulting processed image is the result of applying transformations to the pixel(x,y) of the original image.
Region-based methods: The pixels in the original image are grouped forming a contiguous regions and transformations are applied to the whole region. Example: the resulting pixel(x,y) is the mean of a patch around the original pixel (x,y).

Opencv C++ finding movement in a thresholded image

I am using openCv with C++ and I am trying to find a moving ball under different lighting conditions. So far I am able to filter an image by thresholding it using HSV color space. The problem with this is that it will pick up other object that have a similar color. It is very tedious to figure out the exact hsv range everytime there is a ball with different color/background.
Is there a way for me to apply any filter on the thresholded binary image to detect only the objects that are moving? This way I will only find the ball and not other objects since they are usually stationary.
Thank you,
Varun
Simplest approach would be frame differencing / background learning in an image sequence.
frame differencing: substract two successive frames, the result is the moving part (you will probably only get the edges of moving objects)
background learning: e.g. build an average over 50 frames, this would be your learned background, then substract the current frame, again the difference is the moving part