I have a Canny Edge Detection Code written in C++. I would like to know how can I make it more robust in terms of detecting all the edges correctly and save it? Is this the best possible edge detection possible? Can the coders find any error in my code? Below is a picture of how the code looks like.

#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/// Global variables

Mat src, src_gray;
Mat dst, detected_edges;

int edgeThresh = 1;
int lowThreshold;
int const max_lowThreshold = 100;
int ratio = 3;
int kernel_size = 3;
char* window_name = "Edge Map";

 * @function CannyThreshold
 * @brief Trackbar callback - Canny thresholds input with a ratio 1:3
void CannyThreshold(int, void*)
  /// Reduce noise with a kernel 3x3
  blur( src_gray, detected_edges, Size(3,3) );

  /// Canny detector
  Canny( detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );

  /// Using Canny's output as a mask, we display our result
  dst = Scalar::all(0);

  src.copyTo( dst, detected_edges);
  imshow( window_name, dst );

/** @function main */
int main( int argc, char** argv )
  /// Load an image
  src = imread( argv[1] );

  if( !src.data )
  { return -1; }

  /// Create a matrix of the same type and size as src (for dst)
  dst.create( src.size(), src.type() );

  /// Convert the image to grayscale
  cvtColor( src, src_gray, CV_BGR2GRAY );

  /// Create a window
  namedWindow( window_name, CV_WINDOW_AUTOSIZE );

  /// Create a Trackbar for user to enter threshold
  createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold );

  /// Show the image
  CannyThreshold(0, 0);

  /// Wait until user exit program by pressing a key

  return 0;

enter image description here

  • \$\begingroup\$ Hey mvr950, could you maybe tell us what version of C++ and OpenCV you are using? \$\endgroup\$ – IEatBagels Dec 3 at 14:05
  • \$\begingroup\$ g++ -v gave me gcc version 6.3.0 20170516 (Debian 6.3.0-18+deb9u1) opencv on synaptic is lsb_release -a No LSB modules are available. Distributor ID: Debian Description: Debian GNU/Linux 9.3 (stretch) Release: 9.3 Codename: stretch \$\endgroup\$ – mvr950 Dec 3 at 14:28
  • \$\begingroup\$ There are better edge detectors that utilize machine learning but they are slower and harder to manage. Also there are other classic edge detectors. It is hard to say which detectors are better in general because some are suited to certain tasks while others are faster. \$\endgroup\$ – ALX23z 2 days ago

In terms of making more robust, a fairly obvious improvement would be to ensure that argv[1] exists before using it (that's what argc is for). If there's no argument, or the file can't be read, emit a useful error message to std::cerr and return EXIT_FAILURE - negative return values from main() can vary by platform.

Why do we declare CannyThreshold with two arguments, but never use them? Just declare it taking no arguments.

Your description mentions saving the result, but I don't see any code for that - did you perhaps show us the wrong version of the program?

  • \$\begingroup\$ I wanted to know about the best method to save an image in jpg or png format. \$\endgroup\$ – mvr950 Dec 3 at 14:42
  • 1
    \$\begingroup\$ That's not how Code Review works - you should have implemented to the best of your ability and shown that. We can't review code that's missing! \$\endgroup\$ – Toby Speight Dec 3 at 15:05
  • \$\begingroup\$ Sorry. Thanks for pointing that out. \$\endgroup\$ – mvr950 Dec 3 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.