gpt4 book ai didi

image-processing - 二进制图像上的快速像素计数 - ARM neon 内在函数 - iOS Dev

转载 作者:行者123 更新时间:2023-12-02 03:49:39 25 4
gpt4 key购买 nike

有人可以告诉我一个快速函数来计算二进制图像中白色像素的数量。我需要它用于 iOS 应用程序开发。我直接处理定义为的图像的内存

  bool *imageData = (bool *) malloc(noOfPixels * sizeof(bool));

我正在实现该功能

             int whiteCount = 0;
for (int q=i; q<i+windowHeight; q++)
{
for (int w=j; w<j+windowWidth; w++)
{
if (imageData[q*W + w] == 1)
whiteCount++;
}
}

这显然是最慢的函数。我听说 iOS 上有 ARM Neon 内在函数可用于在 1 个周期内执行多个操作。也许这就是要走的路?

问题是我不太熟悉,目前没有足够的时间学习汇编语言。因此,如果任何人都可以发布针对上述问题的 Neon 内在函数代码或任何其他 C/C++ 快速实现,那就太好了。

我能在网上找到的neon内在函数中唯一的代码是rgb到gray的代码 http://computer-vision-talks.com/2011/02/a-very-fast-bgra-to-grayscale-conversion-on-iphone/

最佳答案

首先,您可以通过分解乘法并摆脱分支来稍微加快原始代码的速度:

 int whiteCount = 0;
for (int q = i; q < i + windowHeight; q++)
{
const bool * const row = &imageData[q * W];

for (int w = j; w < j + windowWidth; w++)
{
whiteCount += row[w];
}
}

(假设 imageData[] 是真正的二进制,即每个元素只能是 0 或 1。)

这是一个简单的 NEON 实现:

#include <arm_neon.h>

// ...

int i, w;
int whiteCount = 0;
uint32x4_t v_count = { 0 };

for (q = i; q < i + windowHeight; q++)
{
const bool * const row = &imageData[q * W];

uint16x8_t vrow_count = { 0 };

for (w = j; w <= j + windowWidth - 16; w += 16) // SIMD loop
{
uint8x16_t v = vld1q_u8(&row[j]); // load 16 x 8 bit pixels
vrow_count = vpadalq_u8(vrow_count, v); // accumulate 16 bit row counts
}
for ( ; w < j + windowWidth; ++w) // scalar clean up loop
{
whiteCount += row[j];
}
v_count = vpadalq_u16(v_count, vrow_count); // update 32 bit image counts
} // from 16 bit row counts
// add 4 x 32 bit partial counts from SIMD loop to scalar total
whiteCount += vgetq_lane_s32(v_count, 0);
whiteCount += vgetq_lane_s32(v_count, 1);
whiteCount += vgetq_lane_s32(v_count, 2);
whiteCount += vgetq_lane_s32(v_count, 3);
// total is now in whiteCount

(这假设 imageData[] 是真正的二进制, imageWidth <= 2^19sizeof(bool) == 1 。)

<小时/>

unsigned char 的更新版本白色值为 255,黑色值为 0:

#include <arm_neon.h>

// ...

int i, w;
int whiteCount = 0;
const uint8x16_t v_mask = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
uint32x4_t v_count = { 0 };

for (q = i; q < i + windowHeight; q++)
{
const uint8_t * const row = &imageData[q * W];

uint16x8_t vrow_count = { 0 };

for (w = j; w <= j + windowWidth - 16; w += 16) // SIMD loop
{
uint8x16_t v = vld1q_u8(&row[j]); // load 16 x 8 bit pixels
v = vandq_u8(v, v_mask); // mask out all but LS bit
vrow_count = vpadalq_u8(vrow_count, v); // accumulate 16 bit row counts
}
for ( ; w < j + windowWidth; ++w) // scalar clean up loop
{
whiteCount += (row[j] == 255);
}
v_count = vpadalq_u16(v_count, vrow_count); // update 32 bit image counts
} // from 16 bit row counts
// add 4 x 32 bit partial counts from SIMD loop to scalar total
whiteCount += vgetq_lane_s32(v_count, 0);
whiteCount += vgetq_lane_s32(v_count, 1);
whiteCount += vgetq_lane_s32(v_count, 2);
whiteCount += vgetq_lane_s32(v_count, 3);
// total is now in whiteCount

(假设 imageData[] 的白色值为 255,黑色值为 0,并且 imageWidth <= 2^19 。)

<小时/>

请注意,上述所有代码均未经测试,可能需要进一步的工作。

关于image-processing - 二进制图像上的快速像素计数 - ARM neon 内在函数 - iOS Dev,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8887118/

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