)
目录1. 简介2. 图像数据2.1 变量理解2.2 生成图像(随机数据)2.3 调取(传递)图像数据2.4 Filter2D函数3. 总结1. 简介通过 HLS 中提供的函数 Filter2D了解在硬件加速中图像数据在 DDR 中的存储模式从而理解的生成、调取方法方便快速测试和验证。1基本概念HWC 和 CHW高度(Height)、宽度(Width)、颜色通道(Channel)HWC图片为 RGB 256×256其在 HWC 格式下的表示为 [256, 256, 3]图像数据首先按照图像的高度和宽度排列对于图像中的任意一个像素点其 RGB 三个颜色通道的值是连续存储的。这种存储方式比较直观。CHW图片为 RGB 256×256在CHW格式下的表示为[3, 256, 256]。数据首先按颜色通道分布对于同一颜色通道内的数据则按照图像的高度和宽度顺序排列。对于图像中的任意一个像素点其RGB三个颜色通道的值在内存中是分开、不连续存储的。这种方式在某些图像处理和深度学习框架中比较常见它能提高某些类型的计算效率。2. 图像数据2.1 变量理解unsigned stride ceil(width/64.0)*64; // width 1080, stride 1088 unsigned nbytes (stride*height); // 图像的一个通道在内存中的大小1Stridestride 表示图像数据中一行像素的实际占用字节数。由于内存对齐的要求或为了提高访问效率图像的实际行宽度stride可能会比基于像素宽度直接计算的值更大。在这个例子中width 是 1080 像素通过 ceil(width / 64.0) * 64 计算得到 stride 为 1088 字节。这是因为内存对齐到 64 字节的倍数。2nbytesnbytes 表示图像的一个通道在内存中的总大小。它是 stride 和 height 的乘积。在这个例子中如果 height 是 720 像素那么 nbytes 就是 1088 * 720 字节。2.2 生成图像(随机数据)为图像的每个颜色通道分配内存空间然后初始化这些内存空间。目的初始化分配的内存空间。rand()为 y_src、u_src 和 v_src 分配随机值模拟图像数据。0将 y_dst、u_dst 和 v_dst 初始化为 0准备存储处理后的图像数据。//每个通道分别申请内存空间CHW存储模式 unsigned char *y_src (unsigned char *)malloc(nbytes); unsigned char *u_src (unsigned char *)malloc(nbytes); unsigned char *v_src (unsigned char *)malloc(nbytes); unsigned char *y_dst (unsigned char *)malloc(nbytes); unsigned char *u_dst (unsigned char *)malloc(nbytes); unsigned char *v_dst (unsigned char *)malloc(nbytes); for (int i0; inbytes; i) { y_src[i], u_src[i], v_src[i] rand(), rand(), rand(); y_dst[i], u_dst[i], v_dst[i] 0, 0, 0; }2.3 调取(传递)图像数据功能对源图像数据应用滤波器并将结果存储在目标图像数据中。float factor filterFactors[filterType]; short bias filterBiases[filterType];actor 和 bias从预定义的滤波器参数数组中获取当前滤波器类型的缩放因子和偏置值。这些参数用于滤波器计算。#pragma omp parallel for num_threads(3) for (int n0; nnumRuns; n) { // Compute reference results Filter2D(filterCoeffs[filterType], factor, bias, width, height, stride, y_src, y_dst); Filter2D(filterCoeffs[filterType], factor, bias, width, height, stride, u_src, u_dst); Filter2D(filterCoeffs[filterType], factor, bias, width, height, stride, v_src, v_dst); }OpenMP 并行化使用 OpenMP 指令 #pragma omp parallel for 并行执行循环指定使用 3 个线程。numRuns表示要执行的滤波操作的次数。Filter2D 函数对每个颜色通道Y、U、V分别应用二维滤波器。这段代码通过并行化处理提高了对图像数据的滤波效率。每个颜色通道Y、U、V分别应用滤波器并行执行可以显著减少处理时间。2.4 Filter2D函数Filter2D 函数的主要功能是对图像应用二维滤波器。Filter2D(…,… …) { for(int y0; yheight; y) { for(int x0; xwidth; x) { // Apply 2D filter to the pixel window int sum 0; for(int row0; row FILTER_V_SIZE; row) { for(int col0; col FILTER_H_SIZE; col) { unsigned char pixel; int xoffset (xcol-(FILTER_H_SIZE/2)); int yoffset (yrow-(FILTER_V_SIZE/2)); // Deal with boundary conditions : clamp pixels to 0 when outside of image if ( (xoffset0) || (xoffsetwidth) || (yoffset0) || (yoffsetheight) ) { pixel 0; } else { pixel src[yoffset*stridexoffset]; } sum pixel*coeffs[row][col]; } } unsigned char outpix MIN(MAX((int(factor * sum)bias), 0), 255); //归一化饱和处理 dst[y*stridex] outpix;}}解释 offsetxoffset 和 yoffset 用于计算当前滤波器元素对应的图像像素位置。xoffset (x col - (FILTER_H_SIZE / 2)) 和 yoffset (y row - (FILTER_V_SIZE / 2)) 确保滤波器中心对准当前像素点 (x, y)。边界处理检查 xoffset 和 yoffset 是否超出图像边界。如果超出边界将 pixel 设为 0否则从源图像 src 中获取对应像素值。3. 总结本文介绍了在硬件加速中使用 HLS 提供的 Filter2D 函数处理图像数据的过程。HWC 和 CHW 两种图像数据存储格式及其应用场景。图像数据在内存中的存储方式包括 stride 和 nbytes 的计算方法。展示生成随机图像数据并使用 OpenMP 并行化处理对图像数据应用滤波器。简单分析了 Filter2D 函数的实现细节。