OpenCV はこれまで,画像や行列の要素にアクセスする様々な方法を提供してきましたが,高速かつ使いやすい方法は存在しませんでした. OpenCV 2.x では,新しいデータ構造と共に別のアクセス方法が導入され,おそらく以前よりも便利になっています. この操作の詳細については, Mat() と Mat_ の説明を参照してください. ここでは,この新しい要素アクセス処理を利用して,レトロ写真の例を(簡潔に)書き直します:
...
// 画像を色平面毎に分割します.
vector<Mat> planes;
split(img_yuv, planes);
// 方法 1. Y 平面をイテレータを用いて処理します.
MatIterator_<uchar> it = planes[0].begin<uchar>(),
it_end = planes[0].end<uchar>();
for(; it != it_end; ++it)
{
double v = *it*1.7 + rand()
*it = saturate_cast<uchar>(v*v/255.);
}
// 方法 2. 1 番目の彩度平面を事前に保存した行ポインタを用いて処理します.
// 方法 3. 2 番目の彩度平面を個々の要素に対するアクセスを用いて処理します.
for( int y = 0; y < img_yuv.rows; y++ )
{
uchar* Uptr = planes[1].ptr<uchar>(y);
for( int x = 0; x < img_yuv.cols; x++ )
{
Uptr[x] = saturate_cast<uchar>((Uptr[x]-128)/2 + 128);
uchar& Vxy = planes[2].at<uchar>(y, x);
Vxy = saturate_cast<uchar>((Vxy-128)/2 + 128);
}
}
merge(planes, img_yuv);
...