实现方式
SIMD 加速
使用 AVX 指令 (mm256*) 实现了并行处理,每次处理 32 个像素。
使用 cmpgt_epi8 进行并行比较,生成掩码。
掩码与常量 255 结合生成二值化结果。
多线程
使用 OpenMP 的 #pragma omp parallel for 将图像像素分块,并行执行。
内存分配
void highPerformanceThresholding(
uint8_t* inputImage, // 输入图像数据
int width, // 图像宽度
int height, // 图像高度
uint8_t lowerThreshold, // 二值化下限
uint8_t upperThreshold, // 二值化上限
uint8_t* outputImage) // 输出二值化结果
{
int totalPixels = width * height; // 总像素数
int blockSize = 256; // 每线程处理的块大小(根据 L1/L2 缓存大小调整)
// 条件判断:图像总像素数大于阈值时启用多线程
const int parallelThreshold = 100000; // 假设阈值为 100,000 像素
if (totalPixels > parallelThreshold) {
// 启用多线程
#pragma omp parallel for schedule(static)
for (int blockStart = 0; blockStart < totalPixels; blockStart += blockSize) {
int blockEnd = blockStart + blockSize; // 块结束位置
if (blockEnd > totalPixels) blockEnd = totalPixels;
for (int i = blockStart; i < blockEnd; i += 32) {
__m256i pixelData = _mm256_loadu_si256((__m256i*)&inputImage[i]);
__m256i lowerThresholdVec = _mm256_set1_epi8(lowerThreshold);
__m256i upperThresholdVec = _mm256_set1_epi8(upperThreshold);
__m256i maskLower = _mm256_cmpgt_epi8(pixelData, lowerThresholdVec);
__m256i maskUpper = _mm256_cmpgt_epi8(upperThresholdVec, pixelData);
__m256i binaryMask = _mm256_and_si256(maskLower, maskUpper);
__m256i binaryResult = _mm256_and_si256(binaryMask, _mm256_set1_epi8(255));
_mm256_storeu_si256((__m256i*)&outputImage[i], binaryResult);
}
}
} else {
// 不启用多线程,单线程处理
for (int i = 0; i < totalPixels; i += 32) {
__m256i pixelData = _mm256_loadu_si256((__m256i*)&inputImage[i]);
__m256i lowerThresholdVec = _mm256_set1_epi8(lowerThreshold);
__m256i upperThresholdVec = _mm256_set1_epi8(upperThreshold);
__m256i maskLower = _mm256_cmpgt_epi8(pixelData, lowerThresholdVec);
__m256i maskUpper = _mm256_cmpgt_epi8(upperThresholdVec, pixelData);
__m256i binaryMask = _mm256_and_si256(maskLower, maskUpper);
__m256i binaryResult = _mm256_and_si256(binaryMask, _mm256_set1_epi8(255));
_mm256_storeu_si256((__m256i*)&outputImage[i], binaryResult);
}
}
}
使用示例
int main() {
// 示例图像大小和阈值
int width = 1920;
int height = 1080;
uint8_t lowerThreshold = 50;
uint8_t upperThreshold = 200;
// 分配图像数据(内存对齐以加速 SIMD 操作)
uint8_t* inputImage = (uint8_t*)aligned_alloc(32, width * height);
uint8_t* outputImage = (uint8_t*)aligned_alloc(32, width * height);
// 初始化图像数据(示例用随机数填充)
for (int i = 0; i < width * height; i++) {
inputImage[i] = rand() % 256;
}
// 执行二值化
highPerformanceThresholding(inputImage, width, height, lowerThreshold, upperThreshold, outputImage);
// 清理内存
free(inputImage);
free(outputImage);
return 0;
}