AvicScalar avic_mat_add_square(const AvicMat* src) - 计算矩阵元素平方和
AvicScalar avic_mat_add_square(const AvicMat* src)
{
int src_cn = AVICCV_MAT_CN(src->type);
int depth = AVICCV_MAT_DEPTH(src->type);
int elem_size = AVICCV_ELEM_SIZE(src->type);
int size = elem_size / src_cn;
int i, j, k, size_multi_cn = 0;
double sum = 0;
AvicScalar add_square_value;
switch (depth)
{
case AVICCV_8U:
{
for (k = 0; k < src_cn; k++)
{
size_multi_cn = k * size;
sum = 0;
for (i = 0; i < src->rows; i++)
{
for (j = 0; j < src->cols; j++)
{
sum += AVIC_CV_SQR(*(unsigned char*)(src->data.ptr + (i * src->cols + j) * elem_size + size_multi_cn));
}
}
add_square_value.val[k] = sum;
}
break;
}
case AVICCV_32F:
{
if (src_cn == 3)
{
float* src_ptr = src->data.fl;
for (k = 0; k < src_cn; k++)
{
size_multi_cn = k * size;
sum = 0;
for (i = 0; i < src->rows; i++)
{
for (j = 0; j < src->cols; j++)
{
sum += AVIC_CV_SQR(*(float*)(src->data.ptr + (i * src->cols + j) * elem_size + size_multi_cn));
}
}
add_square_value.val[k] = sum;
}
}
else
{
float* src_ptr = src->data.fl;
float add[4] = {0};
float* add_ptr = add;
#ifdef WITH_NEON
#ifdef WITH_OMP
#pragma omp parallel for private(j)
#endif
for (i = 0; i < src->rows; i++)
{
src_ptr = src->data.fl + i * src->cols * elem_size;
float32x4_t re1 = vld1q_f32(add_ptr);
for (j = 0; j < src->cols * src_cn - 3; j += 4)
{
float32x4_t temp = vld1q_f32(src_ptr + j * size_multi_cn);
float32x4_t re = vmulq_f32(temp, temp);
re1 = vaddq_f32(re, re1);
}
add_square_value.val[0] += add[0];
add_square_value.val[0] += add[1];
add_square_value.val[0] += add[2];
add_square_value.val[0] += add[3];
}
#else
#ifdef WITH_OMP
#pragma omp parallel for private(j)
#endif
for (k = 0; k < src_cn; k++)
{
size_multi_cn = k * size;
sum = 0;
for (i = 0; i < src->rows; i++)
{
for (j = 0; j < src->cols; j++)
{
sum += AVIC_CV_SQR(*(float*)(src->data.ptr + (i * src->cols + j) * elem_size + size_multi_cn));
}
}
add_square_value.val[k] = sum;
}
#endif
}
break;
}
}
return(add_square_value);
}
该函数使用循环遍历矩阵的每个元素,并计算其平方值。对于每个通道,将所有元素的平方值累加,最终得到每个通道的平方和。该函数支持8位无符号整型和32位浮点数两种数据类型。
优化部分:
该函数使用NEON和OpenMP进行优化,以提高计算效率。
- NEON优化:当数据类型为32位浮点数时,使用NEON指令集进行向量化计算,可以显著提高计算速度。
- OpenMP优化:使用OpenMP并行化循环,可以充分利用多核CPU的计算能力,进一步提高计算速度。
使用方法:
该函数接受一个指向AvicMat结构体的指针作为参数,该结构体包含矩阵数据和相关信息。函数返回一个AvicScalar结构体,包含每个通道的平方和结果。
示例:
// 创建一个3x3的矩阵
AvicMat mat = avic_mat_create(3, 3, AVICCV_32F, 3);
// 填充矩阵数据
float* data = mat.data.fl;
for (int i = 0; i < 9; i++)
{
data[i] = i + 1;
}
// 计算矩阵元素平方和
AvicScalar sum = avic_mat_add_square(&mat);
// 打印结果
printf("通道0的平方和:%.2f\n", sum.val[0]);
printf("通道1的平方和:%.2f\n", sum.val[1]);
printf("通道2的平方和:%.2f\n", sum.val[2]);
原文地址: http://www.cveoy.top/t/topic/qA9x 著作权归作者所有。请勿转载和采集!