mainvisual

前回、グレースケールで画像にメディアンフィルタをかける実装をしました。 今回は、そのカラーバージョンをします。

グレースケールでのメディアンフィルタ実装記事はこちら

まずはソースコードから

メディアンフィルタはグレースケールとカラーの両方大丈夫です。 しかし、これらの2つは、OpenCVでは取り扱いが少々異なります。

今回は、話を簡単にするために、グレースケールの場合を載せようと思います。

#include <iostream>
#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;


void sort(int arr[], int arr_len){
  for(int i=0; i<arr_len-1; i++){
    for(int j=arr_len-1; j>i; j--){
      if(arr[i] > arr[j]){
        int t = arr[j];
        arr[j] = arr[i];
        arr[i] = t;
      }
    }
  }
}


int main(int argc, char *argv[]) {


    if(argc < 2){
      cerr << "引数は1つ指定する必要があります" << endl;
      cerr << "./a.out <FILE PATH>" << endl;
      return -1;
    }

    string path_name = argv[1];

    int const CV_LOAD_IMAGE_RGB = 1;

    // カラー(3チャンネル)で読み込み
    Mat src = imread(path_name, CV_LOAD_IMAGE_RGB);

    //エラーチェック
    if (!src.data) return -1;


    Mat dst = src.clone();


    for(int y=1; y<src.rows-1; y++){
      for(int x=1; x<src.cols-1; x++){
        int data_r[9], data_g[9], data_b[9];

        for(int n=-1; n<=1; n++){
          for(int m=-1; m<=1; m++){
            Vec3b bgr = src.at<Vec3b>(y+n, x+m);
            data_b[(m+1) + 3*(n+1)] = bgr[0];
            data_g[(m+1) + 3*(n+1)] = bgr[1];
            data_r[(m+1) + 3*(n+1)] = bgr[2];
          }
        }

        sort(data_b, 9);
        sort(data_g, 9);
        sort(data_r, 9);
        dst.at<Vec3b>(y, x) = Vec3b(data_b[4], data_g[4], data_r[4]);

      }
    }


    /* 画像の表示 */
    imshow("Show src image", src);
    imshow("Show dst image", dst);
    /* 入力待機 */
    waitKey(0);
    return 0;
}

使い方

このソースコードをファイルにコピペし、次のコマンドを実行してください

g++ $(pkg-config --cflags opencv) -lopencv_core -lopencv_highgui -lopencv_imgproc main.cpp $(pkg-config --libs opencv)
./a.out <IMAGE PATH>

a.outというバイナリができますので、適当な画像のパスを引数に入れて、実行してみてください!