Thursday, 3 March 2016

OpenCV C++ Code For Horizontal Line Detection

This OpenCV C++ Tutorial is about Horizontal Line Detection i.e. How to Detect Horizontal Edges or Lines in an Image
What is a Line? A line is a straight one-dimensional figure having no thickness and extending infinitely in both directions.
In case of Image Processing it is a continuous set of pixels which have values distinctly different from that of the surrounding pixels.
Recall that for point detection ,we use a mask as show below:
-1-1-1
-18-1
-1-1-1
Thus if the mask or Kernel is moved over uniform intensity the response due to the mask is zero.(Sum of all elements of a mask is zero.
Since a point, in image-processing refer to the pixel of distinct value compared to that of the surrounding pixels.
Hence for Horizontal Line detection, we would have to detect the set of horizontal pixels of distinct values from the surrounding pixels.
And if there are no such set of pixels,the output of it should be zero.
Hence we would be choosing the mask as shown below:
-1-1-1
222
-1-1-1
And we would slide this mask over the whole image to detect horizontal lines.
Here is the Opencv C++ Example of Horizontal Edge/Line Detection below:

//Opencv C++ Example for Detecting Horizontal Lines
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "iostream"
 
using namespace cv;
using namespace std;
 
int main( )
{
    Mat src1,src2;
 int a;
 Scalar intensity1=0;
    src1 = imread("C:\\Users\\arjun\\Desktop\\opencv-test.png", CV_LOAD_IMAGE_GRAYSCALE);
 //If image not found 
 if (!src1.data)                                                                          
     { cout << "No image data \n";  return -1; } 

 src2 = src1.clone();
 cout<<"Enter the mask Size =";
 cin>>a;

 //for loop for counting the number of rows and columns and displaying the pixel value at each point
   for (int i = 0; i < src1.rows-a; i++)  { 
    for (int j = 0; j < src1.cols-a; j++) { 
   Scalar intensity2=0;
   for (int p = 0; p<a; p++) { 
     for (int q = 0; q<a; q++)  { 
       intensity1 = src1.at<uchar>(i+p,j+q); 
       if( (p==(a-1)/2))
       {
      intensity2.val[0] +=(a-1)*intensity1.val[0];
       }
       else
       {
            intensity2.val[0] +=(-1)*intensity1.val[0];
       }
     }
  }
    src2.at<uchar>(i+(a-1)/2,j+(a-1)/2)=intensity2.val[0]/(a*a);
   } 
   }
  //Display the original image
  namedWindow("Display Image");                
  imshow("Display Image", src1); 

  //Display the Low Pass Filtered Image image
  namedWindow("Low Pass Filtered Image");     
  imshow("Low Pass Filtered Image", src2);  
  waitKey(0);
  return 0;
 }
Input:
OpenCV C++ Horizontal Line Detection
Output:
OpenCV C++ Horizontal Line Detection Output

Note: This mask is only applicable for detecting light lines in dark background.
If you want to detect dark lines in light background we need to negate the values of mask(i.e. multiply all the elements of mask with -1.)
If we want to detect the lines irrespective of any background, we need to take the absolute value of the result obtained when mask if moved over the image.
More accurate result can be obtained if we smoothen the image before applying line detection.

No comments:

Post a Comment