gpt4 book ai didi

c++ - 需要帮助矢量化此代码

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:51:39 28 4
gpt4 key购买 nike

我有一个 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 位 channel 中,因为 OpenCV 不对多 channel 图像执行排序。这几乎是我所需要的,但不完全是。对于示例输入,它给了我:

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 是我想要的结果。

可以吗?

最佳答案

我相信这会为您解决问题。它不需要分配或堆栈或排序,但确实假设您的范围是 0-255(例如 uint8)。更大的假设:只有当你有宽行时它才会有性能。如果它们真的是 4 像素宽,那么 i<256 就有点丑陋了。有办法让它消失,但我假设 4 个像素只是一个“例如”。为简单起见。

void processRow (int* rowpos, uint8_t* pixelsForRow, int w) {
uint32_t i, pv, v=0, hist[256]={0};
for (i=0; i<w; i++) hist[pixelsForRow[i]]++;
for (i=0; i<256; i++) {pv=hist[i]; hist[i]=v; v+=pv;}
for (i=0; i<w; i++) rowpos[i] = hist[pixelsForRow[i]]++;
}

好的 - 它是如何工作的?
此函数中的第 1 行声明并清空直方图表。
第 2 行计算直方图。
第 3 行将其转换为计数排序 - 这就是 hist 使用比 uint8 更大的元素大小的原因
第 4 行应用排序后的位置。

有2个技巧;首先,在第 3 行中,直方图“移动了 1 个索引”,这样第一个值始终为“0”,而不是它本来应该是的值,第二个值是第一个计数的值,依此类推。第二个技巧是第 4 行中的“++”——始终确保序数值是唯一的。

让我们根据您的输入试一试:
[32 128 16 64]
第 2 行:[0...1....1....1...1...0] 分别位于索引 [0、16、32、64、128、255]
第 3 行:[0...0....1....2...3...0] 分别位于索引 [0、16、32、64、128、255]
第 4 行:[1, 3, 0, 2] ... 看起来正确

让我们在稍微不同的输入上尝试一下:
[32 128 16 32]
第 2 行:[0...1....2....0...1...0] 分别位于索引 [0、16、32、64、128、255]
第 3 行:[0...0....1....3...3...0] 分别位于索引 [0、16、32、64、128、255]
第 4 行:[1, 3, 0, 2] ... 完美


但我不太确定它是否满足您对矢量化的需求 -- :)

关于c++ - 需要帮助矢量化此代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15360396/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com