简体   繁体   中英

how to find euclidean distance between pixels within a image in opencv

int main(){
    Mat cmp, Ref, Diff;
    cmp = imread("image1.tif", CV_LOAD_IMAGE_UNCHANGED);
    Ref = imread("image2.tif", CV_LOAD_IMAGE_UNCHANGED);
    ShiftChk(cmp, Ref);
    absdiff(cmp, Ref, Diff);
    imshow("difference image", Diff);
    waitKey(0);
    double min, max;
    minMaxLoc(Diff, &min, &max);
    Point min_loc, max_loc;
    minMaxLoc(Diff, &min, &max, &min_loc, &max_loc);
    Size sz = Diff.size();
    cout << "max val : " << max << endl;//5
    cout << "max val: " << max_loc << endl; //[26,38]


    vector<vector<double>>test;
    for (int i = 0; i < Diff.cols; i++) {
        for (int j = 0; j < Diff.rows; j++) {

            Point difference = Diff.at<uchar>(26, 38) - Diff.at<uchar>(j, i);
            double dist = sqrt(difference.x*difference.x + difference.y*difference.y);              
            test.push_back(dist);
        }
    }
}

I am trying to find the Euclidean distance between a single point in an image to all other pixels. The distance values are to be stored in vector test but its showing some error in it. And also I don't know whether the logic I have used is correct to give the right answer(Euclidean distance). Can anyone help me out. Thanks in advance

Error message is:

error C2664: 
'void std::vector<std::vector<double,std::allocator<_Ty>>,std::allocator<std::vector<_Ty,std::allocator<_Ty>>>>::push_back(const std::vector<_Ty,std::allocator<_Ty>> &)' : 
cannot convert argument 1 from 'double' to 'std::vector<double,std::allocator<_Ty>> &&' 

There are two major issues:

  1. You're appending the values to the test vector wrong. You need either to create an intermediate vector and push_back it to test (as shown in @0X0nosugar answer ), or better initialize your vectors with correct dimensions and put the value at the right place.

     vector<vector<double>> test(Diff.rows, vector<double>(Diff.cols)); for (int i = 0; i < Diff.rows; i++) { for (int j = 0; j < Diff.cols; j++) { test[i][j] = ... } } 

    As shown in the snippet above, it's better (and faster) to scan by rows, becuase OpenCV stores images row-wise.

  2. You are not computing the distance between two points. You are in fact taking the difference of the values at two given points and creating a Point object out of this (which makes no sense). Also you can avoid to compute explicitly the euclidean distance. You can use cv::norm :

      test[i][j] = norm(Point(38, 26) - Point(j, i)); // Pay attention to i,j order! 

Putting all together:

Point ref(38, 26);
vector<vector<double>> test(Diff.rows, vector<double>(Diff.cols));
for (int i = 0; i < Diff.rows; i++) {
    for (int j = 0; j < Diff.cols; j++) {
        test[i][j] = norm(ref - Point(j,i));      
    }
}

You declared test as a vector holding elements of type vector<double> . Because of that, test.push_back() will only take arguments of type vector<double> .

You are getting an error because you try to pass the double variable dist as argument.

Use a vector<double> for each column to store the distances (BTW the euclidean distance formula looks ok), then append this to test :

vector<vector<double>>test;
for (int i = 0; i < Diff.cols; i++) {
    vector<double> temp;
    for (int j = 0; j < Diff.rows; j++) {

        Point difference = Diff.at<uchar>(26, 38) - Diff.at<uchar>(j, i);
        double dist = sqrt(difference.x*difference.x + difference.y*difference.y);              
        temp.push_back(dist);
    }
    test.push_back(temp);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM