デモザイク(program3)

  • 2020.06.29 Monday
  • 10:09

 ホワイトバランス補正が終わったら、次はデモザイクです。デモザイクのアルゴリズムは、最も簡単で基本的なデモザイクのバイリニアA(Interface誌2020年7月号特集 AI時代の画像処理教科書参照)を実装することにします。デモザイクはCFA(カラーフィルターアレイ)の配列に依存しますが、最もポピュラーな左上の(0,0)の座標がRRGGB配列にしています。配列が合わないようでしたら、プログラムを書き直すか、convertなどで画像を水平または垂直に1画素シフトすれば4通りの配列には対応出来ます。(斜めベイヤー配列などの特殊な配列は別途プログラミングする必要があります。)

 

デモザイク(program3)のプログラミング

 program2と同様に、program1とは別のprogram3というフォルダを作り、program1program1.cpp,program1.h,ppm.cpp,ppm.h,Makefileをコピーし、program1.cpp,program1.h, Makefileのファイル名と中身に記述してあるprogram1program3に全て変更。program3.cppprogram3.hを赤字のように変更します。

  デモザイク(program3.cpp

/***************************************************

 * Calculate program3 (main file)

 * @file     program3.cpp

 * @author Akihiro Okumura

 * @date    2020.01.03

 ***************************************************/

 

#include "program3.h"

 

/*****************

 * Main function

 *****************/

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

{

                   int                                i = 1;

                   const char *program_name ="program3";

                   char           *file_i = NULL;           // input file

                   char           *file_o = NULL;          // output file

 

                   fprintf(stderr,"<< %s >>¥n", program_name);

                   fprintf(stderr,"2020.01.03 designed by A.Okumura¥n¥n");

 

                   file_i = argv[i++];                           // input file

                   file_o = argv[i++];                          // output file

 

                   /***** Main process *****/

                   if (0 != main_process(file_i, file_o, program_name)) {

                                     return fprintf(stderr, "¥n! Calculation Failed !¥n¥n");

                   }

                   fprintf(stderr, "¥n!!!!! Calculation Succeeded !!!!!¥n¥n");

 

                   return 0;

}

 

/*****************************************************************

 *  main function of calculation

 *****************************************************************/

int main_process(char *infile, char *outfile, const char *program_name)

{

                   int              ppm_pn;

                   int              width, height;

                   int              bits;

                   // ppm header read

                   read_ppm_header(infile, &width, &height, &ppm_pn, &bits);

                   fprintf(stderr, "read ppm header¥n");

 

                   // size set

                   int              datasize = width * height;

 

                   // Memory allocate

                   unsigned short *rdatain = new unsigned short [datasize];

                   unsigned short *gdatain = new unsigned short [datasize];

                   unsigned short *bdatain = new unsigned short [datasize];

                   unsigned short *rdataout = new unsigned short [datasize];

                   unsigned short *gdataout = new unsigned short [datasize];

                   unsigned short *bdataout = new unsigned short [datasize];

 

                   // ppm data read

                   fprintf(stderr, "read ppm¥n");

                   read_ppm(infile, rdatain, gdatain, bdatain, width, height);

 

 

                   // demosaic

 

                   fprintf(stderr, "process¥n");

                   demosaic(rdatain, gdatain, bdatain, rdataout, gdataout, bdataout, width, height, bits);

 

                   // ppm write

                   fprintf(stderr, "write ppm¥n");

                   write_ppm(outfile, rdataout, gdataout, bdataout, width, height, ppm_pn, bits, program_name);

 

                   delete [] rdatain;

                   delete [] gdatain;

                   delete [] bdatain;

                   delete [] rdataout;

                   delete [] gdataout;

                   delete [] bdataout;

 

                   return 0;

}

 

/*****************************************************************

 * demosaic

 *****************************************************************/

void demosaic(const unsigned short *rdatain, const unsigned short *gdatain, const unsigned short *bdatain,

                   unsigned short *rdataout, unsigned short *gdataout, unsigned short *bdataout,

                   int width, int height, int bits)

{

                   // cfa define

                   const int    CFAColor[4] = {0,1,2,3};                // cfa color dim -1:null 0:red 1:green1 2:green2 3:blue

                   int              hp, vp;

                   int              pos;

                   int              maxlevel = (0x01 << bits) - 1;

                   int              xpos1, ypos1;

                   int              pos1;

                   int              i;

 

                   double       dg, dr, db;

 

                   int              pd, cfa_color;

                   const int    xd[9] = { -1, 0, 1, -1, 0, 1, -1, 0, 1 };

                   const int    yd[9] = { -1, -1, -1, 0, 0, 0, 1, 1, 1 };

                   const double                r_filter[4][9] = {

                                     { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0 },

                                     {0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.0},

                                     {0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0},

                                     {0.25, 0.0, 0.25, 0.0, 0.0, 0.0, 0.25, 0.0, 0.25}};

 

                   const double                g_filter[4][9] = {

 

                                     { 0.0, 0.25, 0.0, 0.25, 0.0, 0.25, 0.0, 0.25, 0.0 },

                                     {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0},

                                     {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0},

                                     {0.0, 0.25, 0.0, 0.25, 0.0, 0.25, 0.0, 0.25, 0.0}};

                   const double                b_filter[4][9] = {

                                     { 0.25, 0.0, 0.25, 0.0, 0.0, 0.0, 0.25, 0.0, 0.25 },

                                     {0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0},

                                     {0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.0},

                                     {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}};

 

                   for (vp = 0; vp < height; vp++){

                                     for (hp = 0; hp < width; hp++){

                                                        pos = vp*width + hp;

                                                        pd = cfa_phase(hp, vp);

                                                        cfa_color = CFAColor[pd];

                                                        dr = 0.0;

                                                        dg = 0.0;

                                                        db = 0.0;

                                                        for (i = 0; i < 9; i++){

                                                                           xpos1 = hp + xd[i];

                                                                           ypos1 = vp + yd[i];

                                                                           if ( xpos1 >= 0 && xpos1 < width && ypos1 >= 0 && ypos1 < height ){

                                                                                             pos1 = ypos1*width + xpos1;

                                                                                         dr += (double)rdatain[pos1] * r_filter[cfa_color][i];

                                                                                              dg += (double)gdatain[pos1] * g_filter[cfa_color][i];

                                                                                              db += (double)bdatain[pos1] * b_filter[cfa_color][i];

                                                                              }

                                                         }

                                                        rdataout[pos] = clip(ifix(dr), 0, maxlevel);

                                                        gdataout[pos] = clip(ifix(dg), 0, maxlevel);

                                                        bdataout[pos] = clip(ifix(db), 0, maxlevel);

                                     }        // hp loop end

                   }        // vp loop end

 

                   return;

}

 

int clip(int a, int minlevel, int maxlevel)

{

                   int              ans;

                   ans = a;

                   if(ans >= maxlevel) ans = maxlevel;

                   if(ans <= minlevel) ans = minlevel;

                   return       ans;

}

 

int cfa_phase(int hp, int vp)

 

{

                   const int    CFAPhase[4] = { 0, 1, 2, 3 };

                   int phase = CFAPhase[hp%2+ 2*(vp%2)];

                   return phase;

}

 

int ifix(double  vsum)

{

                   if(vsum > 0.0)        return((long)(vsum + 0.5));

                   else                  return((long)(vsum - 0.5));

}

 

/***** End of File (program3.cpp) *****/

 

  program3のヘッダーファイル( program3.h)

/***************************************************

 * Calculate program3 (header file)

 * @file     program3.h

 * @author Akuhiro Okumura

 * @date    2020.01.03

 ***************************************************/

 

#pragma once

 

#ifdef LINUX

#else

#pragma warning(disable:4996)   //                 fopen

#endif

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <math.h>

 

/***** prototype *****/

// main process

int main_process(char *infile, char *outfile, const char *program_name);

 

void read_ppm_header(char *file, int *width, int *height, int *ppm_pn, int *bits);

void read_ppm(char *file, unsigned short *r_data, unsigned short *g_data, unsigned short *b_data, int width, int height);

void write_ppm(char *file, unsigned short *r_data, unsigned short *g_data, unsigned short *b_data,

                   int width, int height, int ppm_pn, int bits, const char *program_name);

 

void demosaic(const unsigned short *rdatain, const unsigned short *gdatain, const unsigned short *bdatain,

                   unsigned short *rdataout, unsigned short *gdataout, unsigned short *bdataout,

                   int width, int height, int bits);

 

int clip(int a, int minlevel, int maxlevel);

int cfa_phase(int hp, int vp);

int ifix(double  vsum);

 

/***** End of File (program3.h) *****/

 

●program3のコンパイル

必要なファイルが揃ったら次にコンパイルです。

1Ubuntuを起動します。

2Ubuntuのターミナルからディレクトリーを選択し、makeとタイプしてコンパイルします。program3 ppm.o program3.oというファイルが出来ていれば成功です。

 

●program3の実行

 program3.exe   <変換前の画像名>  <変換後の画像名>⏎とタイプしてプログラムを実行させます。<変換前の画像名>は、program2で処理したホワイトバランス後の画像を使います。

$ ./program3.exe DSC00100_wb.ppm DSC00100_dm.ppm

 出力ファイルが出来ていれば、処理終了です。

 DSC00100_dm.ppmをビューアーで見てみます。

  デモザイク(program3)の処理結果

 暗いですが、ちゃんと色は付いてきました。ジッパーノイズや偽色があるのは、原始的なアルゴリズムなので仕方ありません。

 

 この内容は、「Interface誌2020年7月号特集 AI時代の画像処理教科書 第4の記事を、読者の便宜をはかるために加筆修正したものです。(同一内容ではない)、また、ここでのプログラムは、CQ出版社さんのダウンロードページの[7月号 AI時代の画像処理教科書][特集 第4章,第5章 画像処理プログラミング] [関連ファイル一式]からダウンロードできます。

コメント
コメントする








    

calendar

S M T W T F S
   1234
567891011
12131415161718
19202122232425
262728293031 
<< July 2020 >>

selected entries

categories

archives

links

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM