Ask Your Question

adt's profile - activity

2019-02-12 03:46:48 -0600 received badge  Popular Question (source)
2013-11-18 05:52:25 -0600 received badge  Editor (source)
2013-11-18 05:51:33 -0600 asked a question 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???

2013-09-04 10:21:39 -0600 asked a question Sobel filter output from opencv and Matlab different

I am converting some code from matlab to opencv. I tried to use Sobel in opencv but the output of opencv and matlab is completely different what could be the reason. How can I make the ouput of opencv same as matlab? My MATLAB code is :

 [sobel_edges,T,V,H] = edge(rgb2gray(im),'sobel',0.03);
  sobel_angles = atan2(V,H); 
  sobel_weights = (V.*V+H.*H).^0.5;

where 0.03 is the threshold. In opencv when I use the prebuilt Sobel filter the output is completely different that of matlab even the engle and magnitude calculated in openc vis different. The opencv code is:

Mat gray_img=Mat::zeros(img.size(),CV_8U);
Mat gradientX=Mat::zeros(gray_img.size(),CV_64F);
Mat gradientY=Mat::zeros(gray_img.size(),CV_64F);
Mat sobel_edge=Mat::zeros(gray_img.size(),CV_64F);
cvtColor(img, gray_img, CV_BGR2GRAY);
Sobel(gray_img, gradientX, gradientX.type(), 1, 0, 3);
Sobel(gray_img, gradientY, gradientY.type(), 0, 1, 3);
Sobel(gray_img,sobel_edge,sobel_edge.type(),1,1,3);
sobel_edge.convertTo(sobel_edge,CV_8U);
sobel_edge.convertTo(sobel_edge,CV_64F);
sobel_edge=sobel_edge/255.0; //I divided this my 255 becuz in MATLAB the output is between 0 to 1
imshow("Sobel",sobel_edge);

   Mat magnitude(gray_img.size(), CV_64F, cv::Scalar(0.0));
    Mat angles=Mat::zeros(gradientX.size(),CV_64F);
    bool anglesInDegrees = true;
    cartToPolar(gradientX, gradientY, magnitude, angles, anglesInDegrees);

The sobel edge itself is different and the magnitude and angle too, I tried to convert manually too the sobel in opencv by looking at the edge function in matlab but still the output is different because it turns out the filter2D of opencv and imfilter in matlab returns different output. How can I obtain the same output of sobel in matlab and opencv???The code of manually converting sobel of matlab to opencv is:

Mat gray_img=Mat::zeros(img.size(),CV_32FC1);
  cvtColor(img, gray_img, CV_RGB2GRAY);
  double minVal,maxVal;
  cv::Mat gray = cv::Mat(gray_img.size(),CV_32FC1);
  gray_img.convertTo(gray_img,CV_32FC1);
  gray=gray_img/255.0;
  cout<<gray<<endl<<"End";
  double data[]={1,2,1,0,0,0,-1,2,-1};
  Mat op=Mat(3,3,CV_64F,data).clone();
  op=op/8;
  Mat x_mask;
  transpose(op,x_mask);
  cout<<x_mask<<endl;
  Mat y_mask=op.clone();
  int scale=4;
  int offset[]={0,0,0,0};
  double sobel_thresh=0.03;
  Mat bx,by,bx_mul,by_mul,b;
  Point anchor(0,0);
  float delta = 0.0;
  cv::filter2D(gray, bx, CV_32FC1, x_mask, anchor, delta, BORDER_REPLICATE);
   bx=abs(bx);
   imshow("f1",bx);

  cv::filter2D(gray, by, CV_32FC1, y_mask, anchor, delta, BORDER_REPLICATE);
   by=abs(by);
  imshow("by",by);

  pow(bx,2,bx_mul);
      imshow("f2",bx_mul);
  pow(by,2,by_mul);
  b= bx_mul+by_mul;
   imshow("f3",b);

  double cut_off;
  cut_off=pow(sobel_thresh,2);
  Mat sobel_edge(gray.size(),CV_32FC1);
    for(int i=0;i<b.rows;i++)
    {
        for(int j=0;j<b.cols;j++)
        {
            if((b.at<float>(i,j))>cut_off)
            {
                sobel_edge.at<float>(i,j)=1;
            }
            else
            {
               sobel_edge.at<float>(i,j)=0;
            }
        }
    }
    imshow("Sobel_edge",sobel_edge);