画像処理 移動平均法とメディアンフィルタの
このページは以下の読者を対象にしています
実験方法
使用プログラム
visual studio 2017. opencv 4.10で動作確認済み
#include <opencv2/opencv.hpp> #include <string> #include <iostream> #include <random> using namespace cv; //粒状雑音用 std::mt19937 mt{ std::random_device{}() }; //粒状雑音作成 Mat AddNoise(const Mat & img, float ratio) { //乱数生成 std::uniform_int_distribution<int> randrow(0, img.rows - 1); std::uniform_int_distribution<int> randcol(0, img.cols - 1); //点の数を計算 int count = (int)(img.rows * img.cols * ratio); Mat ret = img.clone(); //指定場所にノイズを加える for (int i = 0; i < count; i++) { int x = randcol(mt); int y = randrow(mt); ret.at<cv::Vec3b>(y, x) = cv::Vec3b(255, 255, 255); } return ret; } class Imgs { public: static std::string filepath; Imgs(std::string name, Mat img) : name(name), img(img) {}; Imgs() {}; Mat img; std::string name; void ImOutPut() { //imshow(name, img);//ウィンドウに表示する imwrite(filepath + name + ".png", img);//画像を出力 } }; class Filters { public: static Imgs origin; static Imgs target; static int kernelsize; Imgs filteredimg; Imgs abs; //元画像との差分を取得 void SetAbs() { abs.name = "abs_" + filteredimg.name; absdiff(origin.img, filteredimg.img, abs.img);//元画像との差分を取得 }; //フィルター後と差分画像を出力 void ImOutPut() { filteredimg.ImOutPut(); abs.ImOutPut(); } }; //メディアンフィルタ class MedianImg : public Filters { public: MedianImg() { filteredimg.name = "med_" + std::to_string(kernelsize); medianBlur(target.img, filteredimg.img, kernelsize); //メディアンフィルタ SetAbs(); //元画像との差分を取得 } }; // 移動平均法 class MoveAveImg :public Filters { public: MoveAveImg() { filteredimg.name = "ave_" + std::to_string(kernelsize); blur(target.img, filteredimg.img, Size(kernelsize, kernelsize)); // 移動平均法 SetAbs(); //元画像との差分を取得 } }; Imgs Filters::origin; Imgs Filters::target; int Filters::kernelsize; std::string Imgs::filepath;//データの保管場所path.ここを変えて複数の画像を試す std::string files[3] = { "./data1/", "./data2/", "./data3/" }; int main(int argc, char *argv[]) { for (int i = 0; i < 3; i++) { Imgs::filepath = files[i]; //元画像取得 Filters::origin = Imgs("origin", imread(Imgs::filepath + "img.jpg")); Mat origin_img = Filters::origin.img; //縦横比は維持するように画像を縮小 const float kSize = 125; float targetsize = kSize/ origin_img.cols; resize(origin_img, Filters::origin.img, Size(), targetsize, targetsize); //ノイズ付加 Filters::target = Imgs("target", AddNoise(Filters::origin.img, 0.05f)); for (int i = 3; i < 10; i += 2) { Filters::kernelsize = i;//カーネルサイズを変えてみる // 移動平均法 MoveAveImg moveave; //メディアンフィルタ MedianImg median; //結果表示 Filters::origin.ImOutPut(); Filters::target.ImOutPut(); moveave.ImOutPut(); median.ImOutPut(); } } return 0; }