HOGDescriptor::computeGradient using OpenCV - opencv

I try to compute gradient map using HOGDescriptor.
My code:
HOGDescriptor hog;
hog.compute(faceROI,ders,Size(32,32),Size(0,0),locs);
Mat grad;
Mat sec;
hog.computeGradient(frame_gray, grad, angleofs);
imshow("1", frame_gray);
imshow("2", grad); //here program fails: Unhandled exception at memory location
imshow("3", angleofs); //grad.data = "". Why??
I cant find goot examples of using HOGDescriptor::computeGradient.
Help please!

To visualize OpenCv's HOGDescriptor::Calculate(..), use this, it's amazing.

imshow("2", grad); fails because imshow expects that grad image is a 1, 3 or 4 channel image whereas it is a 2 channel image.
First channel contains the gradient in x direction whereas the second channel contains the gradient in y. You should split the channels in two images to visualize them:
Mat grad_channel[2];
split(grad, grad_channel);
imshow("grad_x", grad_channel[0]);
imshow("grad_y", grad_channel[1]);
Best

Related

concatenate a rotation and a translation of cv::Mat to a eigen

I am doing a 6-dof transformation with the RANSAC given in OpenCV and I now want to convert two matrices of cv::Mat to an Isometry3d of Eigen but I didn't find good examples about this problem.
e.g.
cv::Mat rot;
cv::Mat trsl;
// the rot is 3-by-3 and trsl is 3-by-1 vector.
Eigen::Isometry3d trsf;
trsf.rotation = rot;
trsf.translation = trsl; // I know trsf has two members but it seems not the correct way to do a concatenation.
Anyone give me a hand? Thanks.
Essentially, you need an Eigen::Map to read the opencv data and store it to parts of your trsf:
typedef Eigen::Matrix<double, 3, 3, Eigen::RowMajor> RMatrix3d;
Eigen::Isometry3d trsf;
trsf.linear() = RMatrix3d::Map(reinterpret_cast<const double*>(rot.data));
trsf.translation() = Eigen::Vector3d::Map(reinterpret_cast<const double*>(trsl.data));
You need to be sure that rot and trsl indeed hold double data (perhaps consider using cv::Mat_<double> instead).

Homography matrix in Opencv?

In LATCH_match.cpp in opencv_3.1.0 the homography matrix is defined and used as:
Mat homography;
FileStorage fs("../data/H1to3p.xml", FileStorage::READ);
...
fs.getFirstTopLevelNode() >> homography;
...
Mat col = Mat::ones(3, 1, CV_64F);
col.at<double>(0) = matched1[i].pt.x;
col.at<double>(1) = matched1[i].pt.y;
col = homography * col;
...
Why H1to3p.xml is:
<opencv_storage><H13 type_id="opencv-matrix"><rows>3</rows><cols>3</cols><dt>d</dt><data>
7.6285898e-01 -2.9922929e-01 2.2567123e+02
3.3443473e-01 1.0143901e+00 -7.6999973e+01
3.4663091e-04 -1.4364524e-05 1.0000000e+00 </data></H13></opencv_storage>
With which criteria these numbers were chosen? They can be used for any other homography test for filtering keypoints (as in LATCH_match.cpp)?
I assume that your "LATCH_match.cpp in opencv_3.1.0" is
https://github.com/Itseez/opencv/blob/3.1.0/samples/cpp/tutorial_code/xfeatures2D/LATCH_match.cpp
In that file, you find:
// If you find this code useful, please add a reference to the following paper in your work:
// Gil Levi and Tal Hassner, "LATCH: Learned Arrangements of Three Patch Codes", arXiv preprint arXiv:1501.03719, 15 Jan. 2015
And so, looking at http://arxiv.org/pdf/1501.03719v1.pdf you will find
For each set, we compare the first image against each of the remaining
five and check for correspondences. Performance is measured using the
code from [16, 17]1 , which computes recall and 1-precision
using known ground truth homographies between the images.
I think that the image ../data/graf1.png is https://github.com/Itseez/opencv/blob/3.1.0/samples/data/graf1.png that I show here:
According to the comment Homography matrix in Opencv? by Catree the original dataset is at http://www.robots.ox.ac.uk/~vgg/research/affine/det_eval_files/graf.tar.gz where it is said that
Homographies between image pairs included.
So I think that the homography stored in file ../data/H1to3p.xml is the homography between image 1 and image 3.

how can i removing sinusoidal noise w\ frequency domain in opencv

i'm trying to remove '5 lines' in section, in music papers, my original image is this : http://en.wikipedia.org/wiki/Requiem_(Mozart)#/media/File:K626_Requiem_Mozart.jpg
First, i apply gaussian filter and binarized with threshold (min:100, max 255).
Then applying dft to this image, erase some appropriate lines, and reconstruct image by inverse dft.
i use sample code in opencv documentation, actually i doubt myself that i understand this code. :(
http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html
in this sample code, there's 2 Mats. one is 'complexI' for spectrum, another is 'magI' for actual visualized. the result of cv::dft is complexI, magI is normalized complexI. my question is this. how can i add a black line(to cancel in freq domain) and reconstruct?
OpenCV (now) provides a detailed tutorial on how to deal with periodic noise by spectral filtering: https://docs.opencv.org/trunk/d2/d0b/tutorial_periodic_noise_removing_filter.html
It hinges on using cv::dft(), cv::idft(), cv::mulSpectrums(), and cv::magnitude().
The core function (from the tutorial) to perform the filtering goes like so:
void filter2DFreq(const Mat& inputImg, Mat& outputImg, const Mat& H)
{
Mat planes[2] = { Mat_<float>(inputImg.clone()), Mat::zeros(inputImg.size(), CV_32F) };
Mat complexI;
merge(planes, 2, complexI);
// find FT of image
dft(complexI, complexI, DFT_SCALE);
Mat planesH[2] = { Mat_<float>(H.clone()), Mat::zeros(H.size(), CV_32F) };
Mat complexH;
merge(planesH, 2, complexH);
Mat complexIH;
// apply spectral filter
mulSpectrums(complexI, complexH, complexIH, 0);
// reconstruct the filtered image
idft(complexIH, complexIH);
split(complexIH, planes);
outputImg = planes[0];
}
Refer to the tutorial for more information.

Convert 1 channel image to 3 channel

I am trying to convert a 1 channel image (16 bit) to a 3 channel image in OpenCV 2.3.1. I am having trouble using the merge function and get the following error:
Mat temp, tmp2;
Mat hud;
tmp2 = cv_ptr->image;
tmp2.convertTo(temp, CV_16UC1);
temp = temp.t();
cv::flip(temp, temp, 1);
resize(temp, temp, Size(320, 240));
merge(temp, 3, hud);
error: no matching function for call to ‘merge(cv::Mat&, int, cv::Mat&)’
Can anyone help me with this? Thanks in advance!
If temp is the 1 channel matrix that you want to convert to 3 channels, then the following will work:
cv::Mat out;
cv::Mat in[] = {temp, temp, temp};
cv::merge(in, 3, out);
check the Documenation for more info.
Here is a solution that does not require replicating the single channel image before creating a 3-channel image from it. The memory footprint of this solution is 3 times less than the solution that uses merge (by volting above).
See openCV documentation for cv::mixChannels if you want to understand why this works
// copy channel 0 from the first image to all channels of the second image
int from_to[] = { 0,0, 0,1, 0,2};
Mat threeChannelImage(singleChannelImage.size(), CV_8UC3);
mixChannels(&singleChannelImage, 1, & threeChannelImage, 1, from_to, 3);
It looks like you aren't quite using merge correctly. You need to specify all of the cannels that are to be 'merged'. I think you want a three channel frame, with all the channels identical, in Python I would write this:
cv.Merge(temp, temp, temp, None, hud)
From the opencv documentation:
cvMerge: Composes a multi-channel array from several single-channel arrays or inserts a single channel into the array.

Can not convert with cvMerge,DFT

I am trying to make the dft of one single channeled image, and as cvDft is expecting complex values, I was adviced to merge the original image with another image with all 0's so this last one will be considered as imaginary part.
My problem comes when using cvmerge function,
Mat tmp = imread(filename,0);
if( tmp.empty() )
{cout << "Usage: dft <image_name>" << endl;
return -1;}
Mat Result(tmp.rows,tmp.cols,CV_64F,2);
Mat tmp1(tmp.rows,tmp.cols,CV_64F, 0);
Mat image(tmp.rows,tmp.cols,CV_64F,2);
cvMerge(tmp,tmp1,image);`
It gives me the next error: can not convert cvMAt to cvArr
Anyone could help me? thanks!
1) it seems like you're mixing up 2 different styles of opencv code
cv::Mat (- Mat) is a c++ class from the new version of opencv, cvMerge is a c function from the old version of opencv.
instead of using cvmerge use merge
2) you're trying to merge a matrix (tmp) of type CV_8U (probably) with a CV_64F
use convertTo to get tmp as CV_64F
3) why is your Result & image mats (the destination mat) are initializes to cv::Scalar(2)? i think you're misusing the constractor parameters. see here for more info.
4) you're image mat is a single channel mat and you wanted it as a 2 channel mat (as mentioned in the question), change the declaration to
Mat image(tmp.rows,tmp.cols,CV_64FC2);

Resources