- 画像ピクセルの3チャネルのマトリックスは次のように配置されます。
- [[r11、g11、b11、r12、g12、b12、r13、g13、b13、.........]、[r_ij、g_ij、b_ig、]、[........。 ...]]
- つまり、最初の行には次のようになります。[r11、g11、b11、r12、g12、b12、r13、g13、b13]
- [r11、r12、r13、g11、g12、g13、b11、b12、b13]ではなく、ij番目のピクセルのRGB値が連続しています。
- マスク
- これは、シリコンウエハーの彫刻から来ています。つまり、シリコンウエハー上の領域を選択してボードで覆うと、ボードで覆われている場所を除くすべてが彫刻されます。
-
イメージマスク
-
image \ graphics \ object \ matrixを使用して、処理される画像をカバーし、処理された領域に影響を与えます。
-
- マスクの使用法:
- 関心領域:上記のimage \ graphics \ object \ matrixであり、事前に作成された関心領域マスクと処理される画像を乗算して、関心領域である関心画像を取得します。
- 最初に画像ピクセルの値を取得します:画像ピクセルポインタによる
- Mat.ptr <uchar>(int i = 0)は、ピクセルマトリックスのポインターを取得し、インデックスiは、0から始まる行数を示します。
- const uchar * current = myImage.ptr <uchar>(row);
- 行は変更されず、列はピクセルのピクセル値を取得するように変更されますp(row、col)= current [col];
- 次に、入力画像がucharタイプであることを確認し、CV_Assert関数を使用して区別し、パラメーターがFALSEの場合はERRORを返します。
- CV_Assert(MyImage.depth()== CV_8U);
- 最後に、いくつかのピクセル値が処理されます
- I(i、j)= 5 * I(i、j)-[I(i-1、j)+ I(i + 1、j)+ I(i、j-1)+ I(i、j + 1)]
#include "pch.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <cmath>
using namespace std;
using namespace cv;
int main(int argc, char ** argv)
{
Mat myImage = imread("图片地址");
CV_Assert(myImage.depth() == CV_8U);
namedWindow("mask_demo", WINDOW_AUTOSIZE);
imshow("mask_demo", myImage);
Mat resultImage;
myImage.copyTo(resultImage);
int nchannels = myImage.channels();
int height = myImage.rows;
int cols = myImage.cols;
int width = myImage.cols*nchannels;
for (int row = 1; row < height - 1; row++)
{
const uchar * previous = myImage.ptr<uchar>(row - 1);
const uchar*current = myImage.ptr<uchar>(row);
const uchar* next = myImage.ptr<uchar>(row + 1);
uchar * output = resultImage.ptr<uchar>(row);
for (int col = nchannels; col < nchannels*(myImage.cols - 1); col++)
{
*output = saturate_cast<uchar>(5 * current[col] - previous[col] - next[col] - current[col - nchannels] - current[col + nchannels]);
output++;
}
}
namedWindow("mask_result", WINDOW_AUTOSIZE);
imshow("mask_result", resultImage);
waitKey(0);
return 0;
}
- 図に示すように、行は変更されず、列も変更されます。行を判別するのは簡単ですが、列はより困難です。
- 難しいのは、以前はピクセルマトリックスの具体的な配置を理解していなかったため、クエリを実行した後、次の表を作成しました(11から開始すると仮定)。
- 連続するグレーと白は、ピクセルの下の3つのチャネルの値です
- current [col-nchannels]はg22の添え字です-3はg21の添え字です
- rgbの値は加算と減算に対応します。rチャネルの値を使用してgチャネルの値で計算することはできません。
- API、つまりマスク計算を実行する関数を使用すると、上記よりもはるかに簡単です
- マスクを定義する
- マットカーネル=(Mat_ <char>(3,3)<< 0、-1,0、-1,5、-1、0、-1,0);
- filter2D(src、dst、src.depth()、kernel);
- srcとdstはMatオブジェクトです
- src.depthは、ビットマップの深さ、32、24、8などです。
- フィルタは分類子です
- マスクを定義する
int main(int argc, char ** argv)
{
Mat src,dst;
src = imread("地址");
if(!src.data)
{
cout<<"no imgae";
return -1;
}
namedWindow("src_image", WINDOW_AUTOSIZE);
imshow("src_image", src);
Mat Kernel = (Mat_<char>(3,3)<<0,-1,0,-1,5,-1,0,-1,0);
filter2D(src, dst,src.depth(),Kernel);
namedWindow("kernel_image", WINDOW_AUTOSIZE);
imshow("kernel_image", dst);
waitKey(0);
return 0;
}