我有一个 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)));
我不得不将 8 位值和 8 位序数打包到一个 16 位通道中,因为 OpenCV 不对多通道图像执行排序。这几乎是我需要的,但不完全是。对于示例输入,它给了我:
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
是我想要的结果。
可以做到吗?