点击查看代码
#include "xaxivdma.h" // 引入Xilinx提供的VDMA驱动库
#include "xaxivdma_i.h"
#include "sleep.h" // 引入Xilinx提供的延时函数库
#include "ff.h" // 引入FatFs文件系统库
#define DDR_BASEADDR 0x00000000 // 定义DDR存储器的起始地址
#define VDMA_BASEADDR XPAR_AXI_VDMA_0_BASEADDR // 定义VDMA模块的基地址
#define H_STRIDE 800 // 定义图像水平方向的跨度(即一行像素所占的字节数)
#define H_ACTIVE 800 // 定义图像水平方向的分辨率
#define V_ACTIVE 480 // 定义图像垂直方向的分辨率
#define COUNTS_PER_SECOND (XPAR_CPU_CORTEXA9_CORE_CLOCK_FREQ_HZ)/64 // 定义每秒钟的计数数目
#define VIDEO_LENGTH (H_STRIDE*V_ACTIVE) // 定义视频数据的长度(以字节为单位)
#define VDMA_MM2S_START DDR_BASEADDR + 0x2000000 // 定义VDMA偏移量,用于指定VDMA接收数据的存储地址
static FATFS fatfs; // 定义FatFs文件系统对象
u8 picture[800*480*3]={0}; // 定义图像数据缓冲区大小(尺寸为800x480,并且每个像素由RGB三个分量组成)
u8 picture_reverse[800*480*3]={0}; // 定义反转后的图像数据缓冲区
void Xil_DCacheFlush(void); // 声明函数Xil_DCacheFlush,用于刷新CPU高速缓存
// 显示图像的函数,参数disp_base_addr为显示窗口的起始地址,addr为待显示图像的首地址,size_x和size_y为图像的分辨率,scale_x和scale_y为缩放比例,mode为缩放方式(1表示垂直方向缩放,2表示水平方向缩放,0表示不缩放)
void show_img(u8 *disp_base_addr, u8 *addr, u32 size_x, u32 size_y, u32 scale_x, u32 scale_y, u8 mode)
{
u32 i, j, k, l;
for(j=0;j<size_y/scale_y;j++) // 遍历行
{
for(i=0;i<size_x/scale_x;i++) // 遍历列
{
if (mode == 1) { // 如果是垂直方向缩放
u32 r = 0, g = 0, b = 0;
for(k=0;k<scale_x;k++) {
for(l=0;l<scale_y;l++) {
r += *(addr+((i*scale_x+k)+(j*scale_y+l)*size_x)*3+0); // 累加红色分量
g += *(addr+((i*scale_x+k)+(j*scale_y+l)*size_x)*3+1); // 累加绿色分量
b += *(addr+((i*scale_x+k)+(j*scale_y+l)*size_x)*3+2); // 累加蓝色分量
}
}
*(disp_base_addr+(i+j*size_x/scale_x)*3+0) = r/(scale_x*scale_y); // 计算平均值并存储到显示窗口对应位置的缓冲区中(红色)
*(disp_base_addr+(i+j*size_x/scale_x)*3+1) = g/(scale_x*scale_y); // (绿色)
*(disp_base_addr+(i+j*size_x/scale_x)*3+2) = b/(scale_x*scale_y); // (蓝色)
} else if (mode == 2) { // 如果是水平方向缩放
for(l = 0; l < scale_y; l++) {
for(k = 0; k < scale_x; k++) {
u8 r = *(addr+((i*scale_x+k)+(j*scale_y+l)*size_x)*3+0); // 取出原始图像的RGB三个分量
u8 g = *(addr+((i*scale_x+k)+(j*scale_y+l)*size_x)*3+1);
u8 b = *(addr+((i*scale_x+k)+(j*scale_y+l)*size_x)*3+2);
// 将RGB颜色值转换为灰度值
u8 gray = (u8)(0.2989 * r + 0.5870 * g + 0.1140 * b);
// 对灰度值进行阈值化处理(如果大于等于128,则置为白色255,否则置为黑色0)
u8 binary = (gray >= 128) ? 255 : 0;
*(disp_base_addr+((i*scale_x)+k + ((j*scale_y)+l)*size_x*scale_x)*3+0) = binary; // 存储到显示窗