I have a program that detects objects in a live video stream. I am looking to compensate for the distortion in the camera, I have used the OpenCV calibration tool and produced an XML file with the relevant parameters.
However I am unsure how to then apply this using the undistort function, it is my understanding that this will need to be applied to each frame as it is captured?
void undistort(InputArray src, OutputArray dst, InputArray cameraMatrix, InputArray distCoeffs, InputArray newCameraMatrix=noArray() )
I am having trouble identifying each of these parameters, below is my current understanding.
undistorted(currentFrame, resultsWindow, calibrationFile, notSure, notSure);
Is this function called as below:
if(captureOpen == false){
img_scene = cvCaptureFromFile(videoFeed);
}
while(1) {
image = cvQueryFrame(img_scene);
undistort();
undistorted(currentFrame, resultsWindow, calibrationFile, notSure,
notSure);
No, that will not work. You need to manually read your XML file beforehand and fill the corresponding parameters with the data found in the file. The file should contain the camera matrix (look for cx, cy, fx, fy values) and the distortion parameters (k1, k2, k3, p1, p2, etc.).
The documentation for undistort for 2.4.x is here : http://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#undistort
Typically src is a Mat containing the current frame. dst an output Mat of the same size that will be filled with the undistorted image. You will have to convert that back to your preferred format or display it in the window. cameraMatrix is a 3x3 Mat that you have filled with your camera intrinsics. distCoeffs is usually a 1x4 or 1x5 Mat containing the distorsion coeffs. (Note that p1 and p2 must be written right after k2).
Related
I am doing Inverse Perspective Mapping using opencv C++. I am following this code to get the desired result. Please have a look at the result.
[
I am using opencv c++ remap function. In addition to the current result I need to how to project a pixel from the source image to the distination image. i.e if I click on the pixel (320, 140), how would I get the corresponding pixel i.e (0, 0) in the distination picture.
void remap(InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())
I have the calculated the arguments map1, map2. I guess I have to use them but i don't know how.
Can anyone give me more explanation about the opencv function solvepnp()?
The opencv documentation says
bool cv::solvePnP (
InputArray objectPoints,
InputArray imagePoints,
InputArray cameraMatrix,
InputArray distCoeffs,
OutputArray rvec,
OutputArray tvec,
bool useExtrinsicGuess = false,
int flags = SOLVEPNP_ITERATIVE)
I'm wondering what the objectPoints, imagePoints and cameraMatrix are. I have once calibrated my camera and have a parameter xml file from it, can i use this?
It is used when you have for example a 3D model of an object and you have a view of it in the real world, it will give you an approximate position and orientation of the camera towards the object.
For example:
objectPoints – Array of object points in the object coordinate space, 3xN/Nx3 1-channel or 1xN/Nx1 3-channel, where N is the number of points. vector can be also passed here.
imagePoints – Array of corresponding image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, where N is the number of points. vector can be also passed here.
You can find the rest at this link
I have taken a photo A using an RGB camera. And I know the position of a point g in photo A. The camera needs to do a camera calibration. Now I want to know the position of point g after calibration. I am using the code as following, but I want to get the point position, not image. How can I do that? Can you give me some advice?
initUndistortRectifyMap(
cameraMatrix,
distCoeffs,
Mat(),
Mat(),
Size(640, 480),
CV_32FC1,
map1, map2);
remap(A, B, map1, map2, cv::INTER_LINEAR);
Point2f g = Point2f(...,...);//i want to get the new position of the point not image B
Just get coordinates using maps:
x,y - coordinates after (not before),as pasbi correctly noticed in comments, mapping.
(map1(y,x),map2(y,x)) - coordinates before mapping
In other words:
map1.at<float>(y,x) contains source x coordinates for each destination point
p(x,y).
map2.at<float>(y,x) contains source y coordinates for each destination point
p(x,y).
See documentation on remap function.
best method i found was to recreate a camera matrix, with inverted parameters. work to a certain extent, with like basic images modifications
undistortPoints() is your need。
// src_pts are points in raw(distort) img, rectify_pt_vec are in rectifyImageL
// RL, PL are from stereoRectify()
cv::undistortPoints(src_pts, rectify_pt_vec, cameraMatrixL, distCoeffL, RL, PL);
how to get point in srcimg from dstimg just like pasbi commented below.
I'm working in OpenCV C++ to filtering image color. I want to filter the image using my own matrix. See this code:
img= "c:/Test/tes.jpg";
Mat im = imread(img);
And then i want to filtering/multiply with my matrix (this matrix can replaced with another matrix 3x3)
Mat filter = (Mat_<double>(3, 3) <<17.8824, 43.5161, 4.11935,
3.45565, 27.1554, 3.86714,
0.0299566, 0.184309, 1.46709);
How to multiply the img mat matrix with my own matrix? I'm still not understand how to multiply 3 channel (RGB) matrix with another matrix (single channel) and resulted image with new color.
you should take a look at the opencv documentation. You could use this function:
filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT )
which would give you something like this in your code:
Mat output;
filter2D(im, output, -1, filter);
About your question for 3-channel matrix; it is specified in the documentation:
kernel – convolution kernel (or rather a correlation kernel), a single-channel floating point matrix; if you want to apply different kernels to different channels, split the image into separate color planes using split() and process them individually.
So by default your "filter" matrix will be applied equally to each color plane.
EDIT You find a fully functional example on the opencv site: http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/filter_2d/filter_2d.html
I'm new to openCV using version 2.4.9
I am trying to generate a 3D projection of points from a sequence of images without any knowledge of the camera parameters nor have camera used with me to calibrate. The camera used had a fish eye lens.
I used goodFeaturesToTrack() for detecting feature points followed by LK implementation in openCV to track the feature points in the sequence of images. Using these points I was successfully able to estimate the Fundamental Matrix from findFundamentalMat() and implemented stereoRectifyUncalibrated() to generate rectification homography matrices H1 and H2.Then I have computed Rotation matrix R from H as
R = cameraMatrix^{-1}*H*cameraMatrix
Now I need to undistort my images after rectification. Either by initUndistortRectifyMap() and remap() or directly by undistort(), but both the functions also require "distortion co-efficients" to compute corrected image.
I tried to find various methods to estimate those parameters, neither the documentation of the camera model is made available by the company, nor I could find any other method apart from calibrating camera using chessboards or circles grid.
How do I do it??
Am I doing it right?
Is there any other better method?
Can someone kindly help?
Thanks in Advance.
//Code
//Fundamental Matrix
Mat fundamental_matrix = findFundamentalMat(points[0], points[1], FM_RANSAC, 3, 0.99);
cout<<"F:\n" <<fundamental_matrix<<endl;
//Rectification Homographies
Mat H1, H2,F;
F = fundamental_matrix;
stereoRectifyUncalibrated(points[0],points[1], F, image.size(), H1, H2, 3);
cout<<"H1:\n" <<H1<<endl;
cout<<"H2:\n" <<H2<<endl;
//calculating Rotation matrix from homographic maps
Mat fInv= fundamental_matrix.inv();
R = (fInv)*H1*fundamental_matrix;
// Mat distCoeffs = Mat::zeros(8, 1, CV_64F);
initUndistortRectifyMap(fundamental_matrix, distCoeffs, R, fundamental_matrix, image.size() ,CV_32FC1, map1, map2);
//How to compute distCoeffs without a camera nor prior knowledge.Thank You