Qt+opencv 画像形態フィルタリング: 侵食と拡張の学習

Qt+opencv イメージの腐食と拡張

概要

形態学的操作は、形状に基づく一連の画像処理操作です。出力イメージは、入力イメージに構造要素を適用することによって生成されます。
最も基本的な形態学的操作には、侵食と膨張の 2 つがあります。
腐食や膨張は白い部分(ハイライト部分)の影響であり、黒い部分ではありません。膨張とは画像のハイライト部分を拡大する「フィールド拡張」であり、エフェクト画像は元の画像よりもハイライト部分が大きくなります。腐食とは、元の画像のハイライト部分が腐食する「領域が侵食される」ことを意味し、エフェクト画像のハイライト領域は元の画像よりも小さくなります。
一般的な操作の前に、getStructuringElement を使用して、指定された形状カーネル サイズのカーネル行列の構造要素を取得します。コアの形状はカスタマイズ可能で、長方形、十字、楕円形にすることができます。

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)
};

膨張と腐食は、次のようなさまざまな機能を実行します。

  • ノイズを除去する
  • 独立した画像要素をセグメント化し、画像内の隣接する要素を接続します。
  • 画像内の明らかな最大領域または最小領域を見つける
  • 画像のグラデーションを見つける

拡大する

膨張とは局所領域の最大値を求めることであり、入力画像をカーネルで畳み込み、カーネルがカバーする領域内のピクセルの最大値を計算し、その最大値を指定されたピクセルに代入します。この最大化操作により、明るい領域が「拡大」し始めます。これが拡大効果です。
式:
ここに画像の説明を挿入します
関数プロトタイプ:
void cv::dilate (InputArray src、
OutputArray dst、
InputArray kernel、
Pointアンカー = Point(-1,-1)、
int iterations = 1、
int borderType = BORDER_CONSTANT、
const スカラー & borderValue = morphologyDefaultBorderValue() )
パラメータの説明:
src 入力画像
dst 出力画像
カーネル 拡張操作のカーネル NULL の場合、デフォルトで中央に参照点を持つ 3x3 カーネルが使用されます。
アンカー アンカーポイント
の繰り返し 拡張操作の数、デフォルトは 1
borderType は画像の外側にある種の境界を推測するために使用されます
borderValue 境界が定数の場合の境界値

コード:

// 全局变量
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);
}

結果を示す:
ここに画像の説明を挿入します

腐食

エロージョンは、カバレッジ内の位相ピクセルの最小値を抽出します。
腐食操作を実行する場合、入力画像はカーネルと畳み込まれ、カーネルによってカバーされる領域内のピクセルの最小値が計算され、その最小値が指定されたピクセルに割り当てられ、アンカーのピクセルと置き換えられます。ポイントの位置。
式:
ここに画像の説明を挿入します
関数プロトタイプ:
void erode(InputArray src, OutputArray dst, InputArray kernel,
Pointアンカー = Point(-1,-1), int iterations = 1,
int borderType = BORDER_CONSTANT,
const Scalar& borderValue = morphologyDefaultBorderValue() );
パラメータの説明:
src 入力画像
dst 出力画像
カーネル 拡張演算のカーネル NULL の場合、デフォルトで参照点を中心とした 3x3 カーネルが使用されます。
アンカー アンカーポイント
の繰り返し 拡張操作の数、デフォルトは 1
borderType は画像の外側にある種の境界を推測するために使用されます
borderValue 境界が定数の場合の境界値

テストコード:

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);
}

結果を示す:
ここに画像の説明を挿入します

著者: Feima Programmer
技術交流へようこそ: QQ: 255895056
転載の際は出典を明記し、不適切な点があれば修正してください

おすすめ

転載: blog.csdn.net/haohaohaihuai/article/details/106358831