distortion coefficents with opencv camera calibraton - visual-studio-2010

I'm writing in visual c++ using opencv library. I used calibrateCamera function with a checkboard pattern to extract intrinsic, extrinsic and distortion values. The problem is that I don't know how to use the distCoeffs matrix (1x5) on my 2D points on the CCD. Can someone help me?
Thanks in advance!

The relevant portion of the documentation is
Tangential distortion occurs because the image taking lenses are not perfectly parallel to the imaging plane. Correcting this is made via the formulas:
x_{corrected} = x + [ 2p_1xy + p_2(r^2+2x^2)]
y_{corrected} = y + [ p_1(r^2+ 2y^2)+ 2p_2xy]
So we have five distortion parameters, which in OpenCV are organized in a 5 column one row matrix:
Distortion_{coefficients}=(k_1 k_2 p_1 p_2 k_3)
You can also use undistort, undistort points, or initUndistortRectifyMap combined with remap

Related

Matlab - use of principal components in finding longest axis of shape

I'm trying to use the pca function to find the longest axis of shapes in binary images. These are 2D images, so I'm expecting just two principal components. If I apply pca to the image itself I get many components.
My thoughts on this are that the matrix that pca acts on is treated such that rows are observations and columns are variables, so I need to convert my image into a list of the x,y coordinates of non-zero pixels. What function does this? Trying with find, this is what I have so far:
for k=1:cellnum %for each cell...
[nucleus, nucnum] = bwlabel(B5.*(cell==k)); %label nuclei in cell (Thanks #CapeCode)
if nucnum == 1
% other methods
[row, col] = find(nucleus);
[coeff, ~, eigen] = pca([row, col]);
disp (coeff);
end
I get two pairs of coefficients for each nucleus, as follows:
0.8327 0.5537
-0.5537 0.8327
0.9791 0.2036
-0.2036 0.9791
0.8546 0.5193
-0.5193 0.8546
so... am I actually doing what I think I'm doing?
Thanks,
Olly
Edit: Link to my earlier question regarding identification of overlapping objects, and Cape Code's elegant single-line solution - Matlab - Identifying objects in one image that overlap objects in another

Rectify an Image with Matlab's "camerParams" (Computer Vision System Toolbox)

I'm working on a PIV-Workflow and I'm currently pre-processing the images. I need to get rid of the perspective distortion in the images. I do have the "image processing toolbox" and the "camera calibrator". I already got rid of the lens distortion with "undistortImage();" and the cameraParams object, which is inferred through a chessboard pattern.
First Question: Is it possible to use the cameraParams object to distort the image perspectively, so that my chessboard is rectified in the image?
Second Question: Since I were not able to use the cameraParams object, I tried to use the transformation functions manually. I tried to use pairs of control-points (with cpselection tool, the original image and a generated chessboard-image) and the fitgeotrans(movingPoints, fixedPoints, 'projective'); function to get my tform-object. However I always get the error message:
Error using fitgeotrans>findProjectiveTransform (line 189)
At least 4 non-collinear points needed to infer projective transform.
Error in fitgeotrans (line 102)
tform = findProjectiveTransform(movingPoints,fixedPoints);
I tried a lot of different pairs of control-points (4 pairs or more). But I'm still getting this error. I believe I must overlook something here.
Any help is appreciated, thank you.
Stephan
If you are using one of the calibration images, then all the information you need is in the cameraParams object.
Let's say you are using calibration image 1, and let's call it I.
First, undistort the image:
I = undistortImage(I, cameraParams);
Get the extrinsics (rotation and translation) for your image:
R = cameraParams.RotationMatrices(:,:,1);
t = cameraParams.TranslationVectors(1, :);
Then combine rotation and translation into one matrix:
R(3, :) = t;
Now compute the homography between the checkerboard and the image plane:
H = R * cameraParams.IntrinsicMatrix;
Transform the image using the inverse of the homography:
J = imwarp(I, projective2d(inv(H)));
imshow(J);
You should see a "bird's eye" view of the checkerboard. If you are not using one of the calibration images, then you can compute R and t using the extrinsics function.
Another way to do this is to use detectCheckerboardPoints and generateCheckerboardPoints, and then compute the homography using fitgeotform.

GLSL integration function

Any recommendation on how to implement efficient integral functions, like SumX and SumY, in GLSL shaders?
SumX(u) = Integration with respect to x = I(u0,y) + I(u1,y) +... + I(uN,y); u=normalized x coordinate
SumY(v) = Integration with respect to y = I(x,v0) + I(x,v1) +... + I(x,vN); v=normalized y coordinate
For instance the 5th pixel of the first line would be the sum of all five pixels on the first line. And the last pixel would be the sum of all previous pixels including the last pixel itself.
What you are asking for is called prefix sum or summed area table (SAT) for the 2D case (just so you find online resources more easily).
Summed area tables can be efficiently implemented on the GPU by decomposing into several parrallel prefix sum passes [1], [2].
The prefix sum can be accelerated by using local memory to store intermediate partial sums (see example in OpenCL or example in CUDA, the same can in principle be done in an OpenGL fragment shader as well with image load-store, or in a compute shader: OpenGL Super Bible example, similar example to be found in OpenGL Insights around page 280).
Note that you may quickly run into precision issues as the sum may get quite large for the rightmost (downmost) pixels. Integer or fp16 render targets will most likely result in failure due to overflow or lacking precision, fp32 will work most of the time.

Can you recommend a source of reference data for Fundamental matrix calculation

Specifically I'd ideally want images with point correspondences and a 'Gold Standard' calculated value of F and left and right epipoles. I could work with an Essential matrix and intrinsic and extrinsic camera properties too.
I know that I can construct F from two projection matrices and then generate left and right projected point coordinates from 3D actual points and apply Gaussian noise but I'd really like to work with someone else's reference data since I'm trying to test the efficacy of my code and writing more code to test the first batch of (possibly bad) code doesn't seem smart.
Thanks for any help
Regards
Dave
You should work with ground truth datasets for multi-view reconstructions. I recommend to use the Middlebury Multi-View Stereo datasets. Besides the image data in lossless format, they deliver camera parameters, such as camera pose and intrinsic camera calibration as well as the possibility to evaluate your own multi-view reconstruction system.
Perhaps, the results are not computed by "the" gold standard algorithm proposed in the book of Hartley and Zisserman but you can use it to compute the fundamental matrices you require between two views.
To compute the fundamental matrix F from two projection matrices P1 and P2 refer to the code Andrew Zisserman provides.

Liquify filter/iwarp

I'm trying to build something like the Liquify filter in Photoshop. I've been reading through image distortion code but I'm struggling with finding out what will create similar effects. The closest reference I could find was the iWarp filter in Gimp but the code for that isn't commented at all.
I've also looked at places like ImageMagick but they don't have anything in this area
Any pointers or a description of algorithms would be greatly appreciated.
Excuse me if I make this sound a little simplistic, I'm not sure how much you know about gfx programming or even what techniques you're using (I'd do it with HLSL myself).
The way I would approach this problem is to generate a texture which contains offsets of x/y coordinates in the r/g channels. Then the output colour of a pixel would be:
Texture inputImage
Texture distortionMap
colour(x,y) = inputImage(x + distortionMap(x, y).R, y + distortionMap(x, y).G)
(To tell the truth this isn't quite right, using the colours as offsets directly means you can only represent positive vectors, it's simple enough to subtract 0.5 so that you can represent negative vectors)
Now the only problem that remains is how to generate this distortion map, which is a different question altogether (any image would generate a distortion of some kind, obviously, working on a proper liquify effect is quite complex and I'll leave it to someone more qualified).
I think liquefy works by altering a grid.
Imagine each pixel is defined by its location on the grid.
Now when the user clicks on a location and move the mouse he's changing the grid location.
The new grid is again projected into the 2D view able space of the user.
Check this tutorial about a way to implement the liquify filter with Javascript. Basically, in the tutorial, the effect is done transforming the pixel Cartesian coordinates (x, y) to Polar coordinates (r, α) and then applying Math.sqrt on r.

Resources