OpenCV weight approach for correspondence search and disparities C++ - c++

I have an OpenCV application and I have to implement a correspondence search using varying support weights between two image pair. This work is very similar to "Adaptive Support-Weight Approach for Correspondence Search" by Kuk-Jin Yoon and In So Kweon. The support weights are in a given support window.
I calculate dissimilarity between pixels using the support weights in the two images. Dissimilarity between pixel 'p' and 'Pd' is given by
where Pd and Qd are the pixels in the target image when pixels p and q in the reference image have a disparity value d; Np and Npd are the support weight.
After this, the disparity of each pixel is selected by the WTA (Winner-Takes-All) method as:
What I would like to know is how to proceed starting with the formula of the fig.1 (function computing dissimilarity and weights that I have written), i.e. which pixel to consider? Where to start? What pixel with? Any suggestion?
The final result of the work should be similar to:
What could be a good way to do it?
UPDATE1
Should I start creating a new image, and then consider the cost between the pixel (0,0) and all the other pixels, find the minimum value and set this value as the value in the new image at pixel (0,0) ? And so on with the other pixels?

Related

Get HU values along a trajectory volume

So, what I am trying to do is to calculate the density profile (HU) along a trajectory (represented by target x,y,z and tangent to it) in a CT. At the moment, I am able to get the profile along a line passing through the target and at a certain distance from the target (entrance). What I would like to do is to get the density profile for a volume (cylinder in this case) of width 1mm or so.
I guess I have to do interpolation of some sort along voxels since depending on the spacing between successive coordinates, several coordinates can point to the same index. For example, this is what I am talking about.
Additionally, I would like to get the density profile for different shapes of the tip of the trajectory, for example:
My idea is that I make a 3 by 3 matrix, representing the shapes of the tip, and convolve this with the voxel values to get HU values corresponding to the tip. How can I do this using ITK/VTK?
Kindly let me know if you need some more information. (I hope the images are clear enough).
If you want to calculate the density drill tip will encounter, it is probably easiest to create a mask of the tip's cutting surface in a resolution higher than your image. Define a transform matrix M which puts your drill into the wanted position in the CT image.
Then iterate through all the non-zero voxels in the mask, transform indices to physical points, apply transform M to them, sample (evaluate) the value in the CT image at that point using an interpolator, multiply it by the mask's opacity (in case of non-binary mask) and add the value to the running sum.
At the end your running sum will represent the total encountered density. This density sum will be dependent on the resolution of your mask of the tip's cutting surface. I don't know how you will relate it to some physical quantity (like resisting force in Newtons).
To get a profile along some path, you would use resample filter. Set up a transform matrix which transforms your starting point to 0,0,0 and your end point to x,0,0. Set the size of the target image to x,1,1 and spacing the same as in source image.
I don't understand your second question. To get HU value at the tip, you would sample that point using a high quality interpolator (example using linear interpolator). I don't get why would the shape of the tip matter.

Final Descriptor in SIFT

I am new to computer vision and start to learn a very popular topic in the computer vision community, which is SIFT. But I am confused with one implementation detail:
After the detection of a key point, we have to construct 4 by 4 local histograms, serving as the final SIFT descriptor, right? Each local histogram contains the orientation of a local neighborhood of 4 by 4 pixels. So overall we have 16 times 16 equals 256 pixels, which are within a neighborhood around the key point. So this neighborhood is a 16 by 16 grid of pixels.
But how is this neighborhood determined in details? Is the neighborhood rotated according to the orientation of key point? Are pixels within this 256-pixel neighborhood separate according to the scale at which the key point is detected?
Thanks for all coming help!
First, SIFT keypoints are extracted at multiple scales. The descriptors are computed using the respective scale. So, I would not say 'pixels' since it can be ambiguous. For your question, I would like to quote the original paper (Section 6.1):
First the image gradient magnitudes
and orientations are sampled around the keypoint location, using the scale of the
keypoint to select the level of Gaussian blur for the image.
In order to achieve orientation
invariance, the coordinates of the descriptor and the gradient orientations are rotated relative
to the keypoint orientation.
A Gaussian weighting function with σ equal to one half the width of the descriptor window
is used to assign a weight to the magnitude of each sample point.
I hope this answers your question. Please do not hesitate to ask if something is unclear.

computing likelihood of pixel belonging to an object using gradient orientation

I am working on object estimation on a image, that is tracking. Basically, I use gradient orientation as a feature descriptor of each pixel. I compute the gradient of each pixel and bin the orientation into 9-bin histogram therefore each pixel in the image is represented by a 9-dimension vector.
At initialization step a static foreground and background models are constructed as above.
Now the problem I have is that the background and the foreground are composed of many pixels (say k), therefore I will k x 9 dimension histograms for each pixels. How can I compute the likelihood of each pixel such that I can determine if it belongs to the foreground or background.
If the background and foreground models are constructed using a single histogram than it I can use something like compareHist in opencv. However the tracking result is very poor so I want to work at the pixel level. I cannot think of an appropriate method to compute probabilities for the method I stated above.
Is there any efficient way to do this? One way is to do One vs All (in the model) comparison but this is too exhaustive search approach and is computationally expensive.

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 .

Compute edge for intensity decreases only

I want to find edges in my image, specifically vertical changes in intensity which go from light to dark. Is this possible? I'm using the Canny/Sobel edge detectors in OpenCV but they're picking up edges where the intensity increases, which I don't want.
You can write a custom filter and use cvFilter2D (2D convolution).
To give a very simple example, the convolution kernel {1 0 -1;1 0 -1; 1 0 -1} is a 3x3 filter that can highlight intensity decreases going from left to right. You can threshold the result to get the edges.
You will have to select the right size of the kernel, and also the right values, to suit your images.
Here is a good link that shows how to use cvFilter2d:
Once you understand what these filters do mathematically, it is quite clear what and you have to change. And where in the pipeline this must be. In his answer, Totoro already pointed out that you can pass your own filters to be run.
Sobel edge detection works by first running two filters on the image. These filters give the gradient of the image in X and Y direction. Edges and gradients are linked in the way that a large magnitude of the gradient means that there is a lot of change in the image, which would indicate an edge!
So the next step (iirc) in the Sobel algorithm is to find the magnitude of the gradients. And finally you threshold this, to take only large changes in the image as edges. Finally, you do some edge thinning and hysteresis thresholding along the direction of the edge but that is not very important here.
The important step where you want to be different than the Sobel algorithm is that you care about the direcction of change. If you compute the direction of change from the X and Y gradients (using sine and cosine), then you can filter out edges that only go in the direction you want.
If you just care about vertical changes, you can run a convolution kernel that computes the gradient along the horizontal and take only positive values. All positive values will indicate that there was a vertical change from light to dark. If you want you can do the following processing steps just as Sobel would do.