Ask Your Question
1

How could I use a line as a structuring element for morphology transformations?

asked 2014-11-18 22:58:56 -0600

oCV_newbie gravatar image

I'm using the documentation example More Morphology Transformations (newbie here). In the kernel type, you can select between cross/ellipse/rectangle. I would like to use a 5x1 line or something like that. I found this answer which discusses a rotated ellipse as a structuring element and this other answer about using a external file as a structuring element. Both of which I want to try.

I'm looking at getStructuringElement; I'm afraid this is beyond me at the moment. I can't connect the dots here as in integrate the answers to the example so that I could specify a line to be used as kernel either from the code or by supplying an image file. I reproduce the original example:

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

using namespace cv;

/// Global variables
Mat src, dst;

int morph_elem = 0;
int morph_size = 0;
int morph_operator = 0;
int const max_operator = 4;
int const max_elem = 2;
int const max_kernel_size = 21;

char* window_name = "Morphology Transformations Demo";

/** Function Headers */
void Morphology_Operations( int, void* );

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

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

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

 /// Create Trackbar to select Morphology operation
 createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", window_name, &morph_operator, max_operator, Morphology_Operations );

 /// Create Trackbar to select kernel type
 createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name,
                 &morph_elem, max_elem,
                 Morphology_Operations );

 /// Create Trackbar to choose kernel size
 createTrackbar( "Kernel size:\n 2n +1", window_name,
                 &morph_size, max_kernel_size,
                 Morphology_Operations );

 /// Default start
 Morphology_Operations( 0, 0 );

 waitKey(0);
 return 0;
 }

 /**
  * @function Morphology_Operations
  */
void Morphology_Operations( int, void* )
{
  // Since MORPH_X : 2,3,4,5 and 6
  int operation = morph_operator + 2;

  Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) );

  /// Apply the specified morphology operation
  morphologyEx( src, dst, operation, element );
  imshow( window_name, dst );
  }
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
4

answered 2014-11-19 04:06:38 -0600

thdrksdfthmn gravatar image

updated 2014-11-19 06:29:30 -0600

If you just want to create custom kernels, you just need to create binary Mat:

cv::Mat myker(cv::Mat::zeros(5, 5, CV_8U));
for (int i = 0; i < myker.cols; ++i) myker.ptr< uchar >(i)[2] = 255;

this is an example for a vertical line of 1x5, but you can do what you need. You can use fillPoly for filling the shape if you have a polygon.

I have tested and it seems that the erosion with this line and a rectangle of size (1, 5) is the same for some images. But you can try yourself too (using countNonZeros of the difference between the two Mats)


Remark: The 2 kernels do not produce the same results on all the images, so feel free to create your "line" kernel

edit flag offensive delete link more

Comments

Thank you, I'll try it out!

oCV_newbie gravatar imageoCV_newbie ( 2014-11-19 20:41:04 -0600 )edit

Question Tools

Stats

Asked: 2014-11-18 22:58:56 -0600

Seen: 753 times

Last updated: Nov 19 '14