Qt+opencv image morphology filtering: erosion and expansion learning

Qt+opencv image corrosion and expansion

Overview

Morphological operations are a series of image processing operations based on shapes. An output image is produced by applying structural elements to the input image.
There are two most basic morphological operations: Erosion and Dilation.
Corrosion and expansion are for the white part (highlighted part), not the black part. Dilation is the expansion of the highlighted parts of the image, "field expansion", and the effect image has a larger highlighted area than the original image. Corrosion means that the highlighted parts of the original image are corroded, "the area is eroded", and the effect image has a smaller highlighted area than the original image.
Before general operation, getStructuringElement is used to obtain the structuring elements of the kernel matrix of the specified shape kernel size. The shape of the core can be customized and can be rectangular, cross, or elliptical.

enum MorphShapes {
    
    
    MORPH_RECT    = 0, //!< a rectangular structuring element:  \f[E_{ij}=1\f]
    MORPH_CROSS   = 1, //!< a cross-shaped structuring element:
                       //!< \f[E_{ij} =  \fork{1}{if i=\texttt{anchor.y} or j=\texttt{anchor.x}}{0}{otherwise}\f]
    MORPH_ELLIPSE = 2 //!< an elliptic structuring element, that is, a filled ellipse inscribed
                      //!< into the rectangle Rect(0, 0, esize.width, 0.esize.height)
};

Expansion and corrosion can perform a variety of functions, as follows:

  • eliminate noise
  • Segment out independent image elements and connect adjacent elements in the image
  • Find obvious maximum or minimum areas in the image
  • Find the gradient of an image

Expansion

Dilation is to find the maximum value of the local area. The input image is convolved with the kernel, and the maximum value of the pixels in the area covered by the kernel is calculated, and then the maximum value is assigned to the specified pixel. This maximization operation will lead to The bright area begins to "expand", which is the expansion effect.
Formula:
Insert image description here
Function prototype:
void cv::dilate (InputArray src,
OutputArray dst,
InputArray kernel,
Point anchor = Point(-1,-1),
int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar & borderValue = morphologyDefaultBorderValue() )
Parameter description:
src Input image
dst Output image
kernel The kernel of the expansion operation. When it is NULL, the 3x3 kernel with the reference point in the center is used by default.
anchor anchor point
iterations the number of expansion operations, the default is 1
borderType is used to infer some kind of boundary outside the image
borderValue the border value when the border is a constant

Code:

// 全局变量
Mat srcImage, erosion_dst, dilation_dst;
int erosion_size = 0;
int dilation_elem = 0;
int dilation_size = 0;

ErosionDilation::ErosionDilation(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ErosionDilation)
{
    
    
    ui->setupUi(this);
    
    srcImage = imread("F:/work/opencv/morph/sss.jpg");
    erosion_dst = srcImage.clone();
    dilation_dst = srcImage.clone();
    connect(ui->horizontalSlider,&QSlider::valueChanged,[=](int value)
    {
    
    
        int k_size = 2*value+1;
        ui->label_2->setText(QString("内核大小:%1").arg(k_size));
        //Erosion(value);
        Dilation(value);
    });
    bgrMat2Image(srcImage);
    ui->radioButton_1->setChecked(true);
}

ErosionDilation::~ErosionDilation()
{
    
    
    delete ui;
}

void ErosionDilation::bgrMat2Image(cv::Mat &mat)
{
    
    
    cv::Mat rgb = mat.clone();
    if(mat.channels() == 3)
    {
    
    
        cv::cvtColor(rgb, rgb, CV_BGR2RGB);
        mImage = QImage((const uchar*)(rgb.data),rgb.cols,rgb.rows,rgb.cols*rgb.channels(),QImage::Format_RGB888);
    }
    else if(mat.channels() == 4)
    {
    
    
        cv::cvtColor(mat, mat, CV_BGRA2RGBA);
        mImage = QImage((const uchar*)(mat.data),mat.cols,mat.rows,QImage::Format_ARGB32);
    }
    else
    {
    
    
        cv::cvtColor(mat, mat, CV_GRAY2RGB);
        mImage = QImage((const uchar*)mat.data,mat.cols,mat.rows,QImage::Format_Indexed8);
    }
    mImage.bits();

    //QLabel显示
    ui->label->setPixmap(QPixmap::fromImage(mImage));
}

void ErosionDilation::Dilation(int value)
{
    
    
  int dilation_type;
  if(ui->radioButton_1->isCheckable())
  {
    
    
      dilation_type = MORPH_RECT;
  }
  else if(ui->radioButton_2->isCheckable())
  {
    
    
      dilation_type = MORPH_CROSS;
  }
  else if(ui->radioButton_3->isCheckable())
  {
    
    
      dilation_type = MORPH_ELLIPSE;
  }
  dilation_size = value;

  Mat element = getStructuringElement( dilation_type,
                                       Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       Point( dilation_size, dilation_size ) );
  // 膨胀操作
  dilate( srcImage, dilation_dst, element );
  // 显示
  bgrMat2Image(dilation_dst);
}

Show results:
Insert image description here

corrosion

What corrosion extracts is the minimum value of the phase pixel under coverage.
When performing the erosion operation, the input image is convolved with the kernel, and the minimum value of the pixels in the area covered by the kernel is calculated, and then the minimum value is assigned to the specified pixel and replaces the pixel at the anchor point position.
Formula:
Insert image description here
Function prototype:
void erode( InputArray src, OutputArray dst, InputArray kernel,
Point anchor = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );
Parameter description :
src Input image
dst Output image
kernel The kernel of the expansion operation. When it is NULL, the 3x3 kernel with the reference point in the center is used by default.
anchor anchor point
iterations the number of expansion operations, the default is 1
borderType is used to infer some kind of boundary outside the image
borderValue the border value when the border is a constant

Test code:

void ErosionDilation::Erosion(int value)
{
    
    
  int erosion_type;
  if(ui->radioButton_1->isCheckable() )
  {
    
    
      erosion_type = MORPH_RECT;
  }
  else if(ui->radioButton_2->isCheckable())
  {
    
    
      erosion_type = MORPH_CROSS;
  }
  else if(ui->radioButton_3->isCheckable())
  {
    
    
      erosion_type = MORPH_ELLIPSE;
  }
  erosion_size = value;

  Mat element = getStructuringElement( erosion_type,
                                       Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                       Point( erosion_size, erosion_size ) );

  // 腐蚀操作
  erode( srcImage, erosion_dst, element );
  // 显示
  bgrMat2Image(erosion_dst);
}

Show results:
Insert image description here

Author: Feima Programmer.
Welcome to technical exchange: QQ: 255895056.
Please indicate the source for reprinting. If there is any inappropriateness, please correct me.

Guess you like

Origin blog.csdn.net/haohaohaihuai/article/details/106358831