カラーマトリックス補正(program4)

  • 2020.06.30 Tuesday
  • 16:00

 デモザイクの次はカラーマトリックス補正です。カラーマトリックス補正は、R,G,Bのデータが揃っていないと掛けられないのでデモザイク処理後になります。カラーマトリックスの値もホワイトバランス同様にExifデータに書かれている値を使いますが、メーカーによってはカラーマトリックスの値が載っていない場合もあります。その場合はカラーマトリックス補正を掛けなくても良いようです。また、小数点で記述してある場合もありますが、その時はプログラムを小数点対応に書き直してください。

 

●カラーマトリックス補正(program4)のプログラミング

 program3と同様に、program4のフォルダを作り、program1からprogram1.cpp,program1.h,ppm.cpp,ppm.h,Makefileをコピーし、ファイル名と中身の記述をprogram1からprogram4に全て変更。program4.cpp program4.hを赤字のように変更します。

 

  カラーマトリックス補正(program4.cpp)

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

 * Calculate program4 (main file)

 * @file     program4.cpp

 * @author Akihiro Okumura

 * @date    2020.01.03

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

 

#include "program4.h"

 

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

 * Main function

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

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

{

                   int                                i = 1;

                   const char *program_name ="program4";

                   char           *file_i = NULL;           // input file

                   char           *file_o = NULL;          // output file

                   int                                matrix[10] = {1};          // color_matrix_int

 

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

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

 

                   for (int l = 0; l < 10; l++){

                                     matrix[l] = ( argc > i )? atoi(argv[i]) : 1;

                                     i++;

                   }

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

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

 

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

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

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

                   }

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

 

                   return 0;

}

 

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

 *  main function of calculation

 *

 * @param inFile                          : [in] inputfile name

 * @param outFile                        : [in] outputfile name

 * @retval 0                                                      : success

 * @retval except 0                        : error code

 *

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

int main_process(char *infile, char *outfile, const char *program_name, int matrix[10])

{

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

 

                   // color_matrix

                   fprintf(stderr, "process¥n");

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

 

                   // 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;

}

 

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

 * color_matrix

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

void color_matrix(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 matrix[10])

{

                   int              hp, vp;

                   int              pos;

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

                   int              r, g, b;

 

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

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

                                                        pos = vp*width + hp;

                                                        r = rdatain[pos];

                                                        g = gdatain[pos];

                                                        b = bdatain[pos];

                                                        rdataout[pos] = (unsigned short)clip((matrix[0] * r + matrix[1] * g + matrix[2] * b + matrix[9]/2)/matrix[9], 0, maxlevel);

                                                        gdataout[pos] = (unsigned short)clip((matrix[3] * r + matrix[4] * g + matrix[5] * b + matrix[9]/2)/matrix[9], 0, maxlevel);

                                                        bdataout[pos] = (unsigned short)clip((matrix[6] * r + matrix[7] * g + matrix[8] * b + matrix[9]/2)/matrix[9], 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;

}

 

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

 

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

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

 * Calculate program4 (header file)

 * @file     program4.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, int matrix[10]);

 

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 color_matrix(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 matrix[10]);

 

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

 

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

 

●program4のコンパイル

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

1Ubuntuを起動します。

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

 

●program4の実行

 program4のコンパイルが終わったら、実行させます。

1.コンパイルして出来たprogram4workにコピーします。

2exiftoolを使ってExifデータからカラーマトリックスの値を調べます

 ホワイトバランスと同様にRAWファイルをexiftooExifデータを調べます。α7siiの場合は、Color Matrixの項目がカラーマトリックスの値となります。マトリックスが整数なので、分母はG1024の値を使います。

  Exifデータ(カラーマトリックス

注)ソニーのα7siiで撮影したRAWExifデータです。

 

3.program4.exe <カラーマトリックス係数1〜9> <分母のG> <変換前の画像名>  <変換後の画像名>⏎とタイプしてプログラムを実行させます。<変換前の画像名>は、program3で処理したデモザイク後の画像を使います。

$ ./program4.exe 1331 -177 -130 -35 1213 -154 -36 -40 1100 1024 DSC00100_dm.ppm DSC00100_cm.ppm

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

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

  カラーマトリックス補正(program4)の処理結果

 少しですが、色が鮮明になりました。ゲインを上げて見ると違いが分かります。

 

 この内容は、「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