matlab find function implementation in opencv? - c++

I have this matlab code ,where i tried to find the 'j' in matrix color.I cant find a usefull function in opencv which can do the same job like matlab find do.i have tried some iterative method with 3 for loops ,but that were too cumbersome,Can you guys help me out?
if (find(Colorr==j))
tt=tt+1;
test=[test;ColorValues(:,j,1),ColorValues(:,j,2),ColorValues(:,j,3)];
end
this is the code i have written to covert to opencv
for(j=0;j<ColorValues.cols/2;j++)
for(i=0;i<Color.cols;i++){
if(j=input[Color.step*i+1]){
tt++;
for(k=0;k<ColorValues.rows;k++){
}
}
}

Assuming Color is a properly initialized single-channel cv::Mat, you can use the combination of overloaded operator== and cv::countNonZero() to do what you wish. operator== returns a mask where each element is one if the value in Color matches j, or zero otherwise.
if(cv::countNonZero(Color == j))
{
// Do something...
}

Related

Boolean Not in OpenCV 3.1

I would like to know if there's a simple way of doing a boolean "not" operation on a cv::Mat. This does not work:
cv::Mat mat = cv::Mat::ones(3,3, CV_8U);
cv::Mat mat_not = !mat;
As such, is there an effective or simple way to do this? Should I resort to using something like this:
cv::Mat mat_not = mat < cv::Mat::ones(3,3,CV_8U);
Thanks a lot!
EDIT: I confused the "not" operator between MATLAB and C++ (since I'm translating the first one to the other). This works fine:
cv::Mat map2 = ~map1;
Edit: 12:30pm 7/20/2016
I see the op wants a regular NOT and I'm used to that being different for things like IDL and MatLab etc..
As #cxyzs7, #Cedric, and #Miki mentioned the operator in c++ is ~ so ...
mat = ~mat;
However if you ever want to do something else element wise (for example a bitwise) most of the time there's already a whole function for that. IE...
bitwise_not
cv::Mat src;
src = stuff;
cv::Mat dst;
//then call it
bitwise_not(src,dst);
If the function you want to do element by element is non-existent in the library or isn't an overloaded operator you can always do it the brute force way...
for(...) {
for (...) {
dst.at<int>(i,j) = ! src.at<int>(i,j);
}
}

Fitting 2d gauss function in C++ too slow

I'm trying to fit a 2d gauss function to an image (in cv::Mat format), and I'm using the NLopt library.
I put my object function like this:
for(i for each row)
for(j for each col)
{
//compute the gauss function value
double valuenow=x[0]*exp(-( x[3]*(j-x[1])*(j-x[1]) + 2*x[4]*(j-x[1])*(i-x[2]) + x[5]*(i-x[2])*(i-x[2]) ));
//add square residual to result
result+=(valuenow-fitdata.at<double>(i,j))*(valuenow-fitdata.at<double>(i,j));
}
return result;
My matrix is about 1000*1000 size, I'm using LN_COBYLA algorithm. When I ran this, it turned out to be extremely slow. I think there must be something wrong with the way I specify my object function, because I used to do the same thing in Matlab with lsqnonlinear, which returned in a second.
Can someone help me please? Thanks in advance.
The at<>() function is slow. If speed is of essence, it's not a good idea to use it inside loops. Take a pointer outside the loop and then just use that pointer inside the loop.
A related question:
OpenCV Mat array access, which way is the fastest for and why?

How to get values of a Matrix which are non zero

I am translating some matlab code to c++ using opencv. I want to get the values of a Matrix which satisfies a condition. I created a mask for this and when I apply it to the original Matrix I get the same size of the original matrix but with 0 values which are not there in the mask. But my question is how can I get only the values that are non-zero in the matrix and assign it to a different matrix.
My matlab code is:
for i= 1:size(no,1)
mask= labels==i;
op = orig(mask, :); //op only contains the values from the orig matrix which are in the mask. So orig size and op size is not the same
.....
end
The c++ translation that I have now is:
for (int i=0; i<n.rows; i++)
{
Mat mask;
compare(labels,i,mask,CMP_EQ);
Mat op;
orig.copyTo(op,mask); //Here the orig size and the op size is always same but values which are not in the mask are 0
}
So, how can I create a matrix which only has the values that the mask satisfies???
You might try to make use of cv::SparseMat (http://docs.opencv.org/modules/core/doc/basic_structures.html#sparsemat), which only keeps non-zero values in a hash.
When you assign a regular cv::Mat to a cv::SparseMat, it automatically captures the non-zero values. From that point, you can iterate through the non-zero values and manipulate them as you'd like.
Hope I got question correctly and it helps!
OpenCv does support Matrix Expresions like A > B or A <= Band so on.
This is stated in the Documentation off cv::Mat
If you're simply wanting to store values, the Mat object is probably not the best way, since it has been made for the purpose of containing images.
In that case, use an std::vector object instead of the cv::Mat object, and you can use the .push_back handle whenever you find an element that is non-zero, which will dynamically resize the vector.
If you're trying to create a new image, then you have to be specific about what kind of image you want to see, because if you don't know how many nonzero elements there are, how can you set the width and height? Also you might end up with an odd number of elements.

OpenCV matrix multiplication with unknown number type

I'm having some processing i.e. some matrix operations using Mat in OpenCV and the following line gives error:
matC = matA*matB;
This time, the error is not that difficult to identify since I've already known that the matrix dimensions are correct and their number types are either CV_64FC1 or CV_32FC1.
So, I can fix this error by identifying each matrix's number type (perhaps with some if-else) and replace with a temporary matrix (Mat) that is type compatible
However, in terms of the implementation of OpenCV Mat multiplication, is it a good one? Do we really have to check the operands' number type (and even number of channel e.g. CV_64FC3, CV_64FC2) every time a matrix operation is performed?
is this type of checking barely avoided? since matA or matB are probably returned from a function call such as solvePnP(..., matA, matB,...) and number type of matA, matB are undefined
Thanks,
PS: I've stuck with OpenCV matrix operation several times, problems with number type, number of channels...
Edit 01:
I'm sorry for not being clear in my question! but I'm doing my best to make myself clear
my questions are:
1) should I and how would I do to ensure matC = matA*matB is a error-free operation?
2) in case there should be some checking before the operation, then, should I do that every time such matrix operation is performed? is there a better choice to not replicate such checking?
Edit 02:
here is what I currently do to perform the checking:
tmp1 = Vect32Homo(Mat(objPoints.at<Vec3f>(i)));
if (s1To.depth() != tmp1.depth())
{
printf("Different Number Type!");
s1To.convertTo(s1To, CV_64FC1);
tmp1.convertTo(tmp1, CV_64FC1);
} else
{
printf("Same Number Type!");
}
tmp = s1To*tmp1; // error prone operation
As you may see that this attempt will not work if the two matrices have different number of channel

Integers to Matrix (cvMat)

Hey guys,
I'm working on a project. I need to use the function cvFindHomography in openCV before this step I have applied LK optical flow function, so I get the features in the first frame and in the second frame as INTEGERS, well in cvFindHomography I need to use these features but as cvMat not as integers.
Do you have any I idea how to put these integers in a Matrix in order to use them in the function mentioned above.
Thank you.
You can use the cvMat() constructor:
CV_INLINE CvMat cvMat( int rows, int cols, int type, void* data CV_DEFAULT(NULL))