Ask Your Question
1

Get strength of edges using magnitude

asked 2018-02-19 07:43:33 -0600

Grillteller gravatar image

I am trying to get the strength of detected lines using the gradient magnitude referring to this post: https://stackoverflow.com/questions/3...

I detect lines as vector<Vec4f>with the Line Segment Detector (LSD) in an image and I calculate the magnitude of the same image. Now I want to calculate the strength of a single line using my magnitude Mat. How can I use one line as a mask for my magnitude and calculate for example the sum of all values. My first approach would be to draw a line in the magnitude "image" and sum up all values the line hits. But I think there must be a better approach using the opencv libs?

Here is my code:

void findLines(cv::Mat inputimg, std::vector<cv::Vec4f> &lines, cv::Mat &outputimg) {
   cv::equalizeHist(inputimg, inputimg);

   cv::Mat reduced_noise;
   cv::bilateralFilter(inputimg, reduced_noise, 5, 75, 75, 4);

   cv::Ptr<cv::LineSegmentDetector> Line_detector = cv::createLineSegmentDetector();
   Line_detector->detect(reduced_noise, lines);
   Line_detector->drawSegments(outputimg, lines);
}

void computeMagnitude(Mat img, Mat magn) {

  // Compute dx and dy deratives with Sobel
  Mat dx, dy;
  Sobel(img, dx, CV_32F, 1, 0);
  Sobel(img, dy, CV_32F, 0, 1);

  // Compute gradient 
  magnitude(dx, dy, magn);
}

int main(int argc, char** argv) {
  // Load two images as grayscale images
  Mat img_1, img_2;
  img_1 = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
  img_2 = imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);

  // Test if images could be read
  if (!img_1.data || !img_2.data) {
      cout << "Error reading image" << endl;
      return EXIT_FAILURE;
  }

  Mat magnitude_1;
  vector<Vec4f> lines_1;
  Mat drawing = img_1.clone();

  computeMagnitude(img_1, magnitude_1);
  findLines(img_1, lines_1, drawing);

  // Draw a line in the magnitude image and calculate the sum of all cells it hits ?

 }
edit retag flag offensive close merge delete

Comments

I don't think opencv has a standard way to calculate the magnitude of a given line, so, if you have the coordinates of each line it should be easy to go with your idea and just sum pixel intensities along the line and normalize with line length to get what you want.

Pedro Batista gravatar imagePedro Batista ( 2018-02-19 09:42:23 -0600 )edit
1

cv::LineIterator , maybe ?

berak gravatar imageberak ( 2018-02-20 04:13:16 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
3

answered 2018-02-22 02:42:56 -0600

Grillteller gravatar image

updated 2018-02-22 02:44:25 -0600

I followed both approaches as mentioned in the comments above. First I generate a LineIterator for every single line. Then I get the magnitude values out of the magnitude Mat. After that it is possible to calculate the sum/normalized sum etc. Thanks for the help.

Here is the code:

void computeStrengthOfEdges(Mat magn, vector<Vec4f> lines) {

    vector<float> magnitude_of_line;
    vector<float> strength;

    for (size_t i = 0; i < lines.size(); i++) {

        // Generate a LineIterator for every line
        LineIterator line_iterator(magn, Point2f(lines[i][0], lines[i][1]), Point2f(lines[i][2], lines[i][3]), 8, true);

        for (int j = 0; j < line_iterator.count; j++, ++line_iterator) {
        // Get all values the line hits (8 way-connection) in the magnitude image
            float magnitude_value = magn.at<float>(line_iterator.pos()); 
            magnitude_of_line.push_back(magnitude_value);
        }
        // Calculate the sum all values
        float sum = accumulate(magnitude_of_line.begin(), magnitude_of_line.end(), 0.0);    
        strength.push_back(sum);
        magnitude_of_line.clear();      
    }   
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2018-02-19 07:43:33 -0600

Seen: 1,323 times

Last updated: Feb 22 '18