私は8ビットの画像を持っています。ピクセルごとに、現在の行の順序位置を計算する必要があります。たとえば、行が次の場合:
32 128 16 64,
次に、結果が必要です。
1 3 0 2,
32は行の1番目に高い値であるため、128は3番目に高く、16は0番目に高く、64は2番目に高い値です。
画像のすべての行に対して上記の手順を繰り返す必要があります。ベクトル化されていないコードは次のとおりです。
for (int curr = 0; curr < new_height; ++curr)
{
vector<pair<unsigned char, char> > ordered;
for (char i = 0; i < 4; ++i)
{
unsigned char val = luma24.at<unsigned char>(curr, i);
ordered.push_back(pair<unsigned char, char>(val, i));
}
sort(ordered.begin(), ordered.end(), cmpfun);
for (int i = 0; i < 4; ++i)
signature.at<char>(curr, ordered[i].second) = i;
}
luma24
は私が読んでいる8ビットの画像で、new_height
行と4列があります。 signature
は同じサイズの署名付き画像です(関連性がないため、今のところ記号の違いは無視してください)。ここに結果を保存します。cmpfun
簡単なコンパレータ関数です。
私は上記のコードをベクトル化しようとしましたが、これを取得しました:
Mat ordinal;
luma24.convertTo(ordinal, CV_16UC1, 256, 0);
Mat sorted = ordinal.clone();
for (int i = 0; i < 4; ++i)
ordinal(Range::all(), Range(i, i+1)) += i;
cv::sort(ordinal, sorted, CV_SORT_EVERY_ROW | CV_SORT_ASCENDING);
bitwise_and(sorted, Scalar(0x00ff), ordinal);
Mat ordinal8;
ordinal.convertTo(ordinal8, CV_8SC1, 1, 0);
ordinal8.copyTo(signature(Range::all(), Range(0, 4)));
OpenCVはマルチチャネル画像の並べ替えを実行しないため、8ビット値と8ビット序数を単一の16ビットチャネルにパックする必要がありました。これはほとんど私が必要としているものですが、完全ではありません。入力例の場合、次のようになります。
2 0 3 1
最小値は2列目にあるので、次に低い値は0列目にあります。各ピクセルに個別にアクセスせずに、これを必要な結果に変換するにはどうすればよいですか。
基本的に、私はこれをどういうわけかベクトル化する必要があります:
uint8_t x[] = {2, 0, 3, 1};
uint8_t y[4];
for (uint8_t i = 0; i < 4; ++i)
y[x[i]] = i;
ここx
で、は現在のベクトル化されたコードが私に与える中間結果であり、y
は私が望む結果です。
できますか?