ビデオストリームを処理するように設計されたプログラムの開発中に、画像のコントラストを変更するアルゴリズムを実装する必要が生じました。
このプログラムはビデオ処理を目的としたものであるため、実装にはフルHDビデオ解像度を処理する機能など、高性能が必要でした。 コードは、OpenMPライブラリを使用してC ++で記述されています。
コントラストを変更するためのいくつかのアルゴリズムがあり、そのうちのいくつかはこの記事で検討されています[1]。
コントラストを変更するためのRGBアルゴリズムを検討してください。
最初に、画像の平均輝度IABを計算します。 OpenMPディレクティブを使用して、ループを並列化します。
#pragma omp parallel for private(valueB,valueG,valueR) reduction(+:lAB) schedule(static,1) for (int j = 0; j < ptrImage->imageSize; j = j+3) { valueB = ptrImage->imageData[j]; valueG = ptrImage->imageData[j+1]; valueR = ptrImage->imageData[j+2]; lAB += (int)(valueR * 0.299 + valueG * 0.587 + valueB * 0.114); } // lAB /= imageRows * imageCols;
次に、各色成分R、G、およびBの各画像ピクセルについて、平均輝度値デルタからの偏差を見つけ、この偏差にコントラストkのゲイン(減衰)を掛ける必要があります。 画像内のすべてのピクセルでこれを直接実行すると、操作が高すぎます。 したがって、ピクセルのすべての色成分を同じ方法で変換すると、各色成分のパレットを表す256個の値の配列を導入します。 配列のインデックスは色成分の古い値に対応し、配列の値は変換された値に対応します。 したがって、前述の変換を適用して、パレットのコントラストを変更すると、次のようになります。
// double k = 1.0 + correction / 100.0; for (int i = 0; i < 256; i++) { int delta = (int)i - lAB; int temp = (int)(lAB + k *delta); if (temp < 0) temp = 0; if (temp >= 255) temp = 255; b[i] = (unsigned char)temp; }
次に、画像全体のピクセルに新しい値を適用し、結果のパレット配列を使用して、ピクセルの色成分の古い値と新しい値を比較します。
#pragma omp parallel for firstprivate(b) for (int j = 0; j < ptrImage->imageSize; j++) { unsigned char value = ptrImage->imageData[j]; ptrImage->imageData[j] = (unsigned char)b[value]; }
コントラストを変更する関数のソースコード全体:
const int L = 256; void AddContrastFilter(IplImage* ptrImage, int _correction) { // 4, omp_set_num_threads(4); int correction = _correction; // int b[L]; // int imageRows = ptrImage->height; int imageCols = ptrImage->width; int lAB = 0; unsigned char valueB = 0; unsigned char valueG= 0; unsigned char valueR= 0; // #pragma omp parallel for private(valueB,valueG,valueR) reduction(+:lAB) schedule(static,1) for (int j = 0; j < ptrImage->imageSize; j = j+3) { valueB = ptrImage->imageData[j]; valueG = ptrImage->imageData[j+1]; valueR = ptrImage->imageData[j+2]; lAB += (int)(valueR * 0.299 + valueG * 0.587 + valueB * 0.114); } // lAB /= imageRows * imageCols; // double k = 1.0 + correction / 100.0; //RGB for (int i = 0; i < L; i++) { int delta = (int)i - lAB; int temp = (int)(lAB + k *delta); if (temp < 0) temp = 0; if (temp >= 255) temp = 255; b[i] = (unsigned char)temp; } #pragma omp parallel for firstprivate(b) for (int j = 0; j < ptrImage->imageSize; j++) { unsigned char value = ptrImage->imageData[j]; ptrImage->imageData[j] = (unsigned char)b[value]; } return 0; }
4コアIntel XeonプロセッサでFull HDフレームのコントラストを変更するには、約8ミリ秒かかることがわかりました。
参照資料
1.ソフトウェアのコントラストの変換: http : //www.kweii.com/site/color_theory/Contrast100_en.pdf