一、角点检测算法:FAST
该算法检测的角点定义为在像素点的周围邻域内有足够多的像素点与该点处于不同的区域,应用到灰度图像中,即有足够多的像素点的灰度
值大于该点的灰度值或者小于该点的灰度值。考虑下图中 p 点附近半径为 3 的圆环上的 16 个点,一个思路是若其中有连续的 12 个点的灰度值与 p 点的灰度值差别超过某一阈值,则可以认为 p 点为角点。
二、建立工程
打开HLS创建工程,详细过程就不说明了。在source中添加两个源文件。文件:top.cpp
#include "top.h"
void hls_fast_corner(AXI_STREAM& INPUT_STREAM,AXI_STREAM& OUTPUT_STREAM,int rows,int cols,int threhold)
{
#pragma HLS INTERFACE ap_stable port=cols
#pragma HLS INTERFACE ap_stable port=rows
#pragma HLS INTERFACE ap_stable port=threhold
#pragma HLS INTERFACE axis register both port=OUTPUT_STREAM
#pragma HLS INTERFACE axis register both port=INPUT_STREAM
#pragma HLS RESOURCE core=AXI_SLAVE variable=rows metadata="-bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=cols metadata="-bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=threhold metadata="-bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=return metadata="-bus_bundle CONTROL_BUS"
RGB_IMAGE _src(rows,cols);
RGB_IMAGE _dst(rows,cols);
RGB_IMAGE src0(rows,cols);
RGB_IMAGE src1(rows,cols);
GRAY_IMAGE mask(rows,cols);
GRAY_IMAGE dmask(rows,cols);
GRAY_IMAGE gray(rows,cols);
#pragma HLS dataflow
#pragma HLS STREAM variable=src1.data_stream depth=20000 dim=1
hls::AXIvideo2Mat(INPUT_STREAM, _src);
hls::Scalar<3,unsigned char> color(255,0,0);
hls::Duplicate(_src,src0,src1);
hls::CvtColor<HLS_BGR2GRAY>(src0,gray);
hls::FASTX(gray,mask,threhold,true);
hls::Dilate(mask,dmask);//做膨胀处理
hls::PaintMask(src1,dmask,_dst,color);
hls::Mat2AXIvideo(_dst,OUTPUT_STREAM);
}
hls::Duplicate() :这将输入图像复制到两个单独的输出图像中,我们可以并行处理这些图像。
typedef hls::Scalar<3, unsigned char> RGB_PIXEL;//“3”表示定义三通道的彩色图像(2为灰度图),上语句的作用就是RGB图像像素数据的线性变换
cv::cvtColor()用于将图像从一个颜色空间转换到另一个颜色空间的转换(目前常见的颜色空间均支持),并且在转换的过程中能够保证数据的类型不变,即转换后的图像的数据类型和位深与源图像一致。
详细请看【传送门】
文件2:top.h
#ifndef _TOP_H_
#define _TOP_H_
#include "hls_video.h"
//maximum image size
#define MAX_WIDTH 1281//图片的尺寸大小
#define MAX_HEIGHT 720
// i/O image seting
#define INPUT_IMAGE "test_1080p.bmp"//测试图片的名称,记得修改图片名称
#define OUTPUT_IMAGE "result.bmp"
#define OUTPUT_IMAGE_GOLDEN "result_golden.bmp"
//typedef video library core structures
typedef hls::stream<ap_axiu<32,1,1,1> > AXI_STREAM;
typedef hls::Scalar<3,unsigned char> RGB_PIXEL;
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> RGB_IMAGE;
typedef hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC1> GRAY_IMAGE;
//top level function for Hw synthesis
void hls_fast_corner(AXI_STREAM& INPUT_STREAM,AXI_STREAM& OUTPUT_STREAM,int rows,int cols,int threhold);
#endif
有这两个文件就可以综合了,综合前需要设置入口函数,按照提示来就可以了。
接下来添加测试文件,在test bench中右键添加:tb.cpp
#include "hls_opencv.h"
#include "top.h"
using namespace cv;
int main(int argc,char** argv){
IplImage* src=cvLoadImage(INPUT_IMAGE);
IplImage* dst=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
cvShowImage("hls_src",src);
//hls视频库处理
AXI_STREAM src_axi,dst_axi;
IplImage2AXIvideo(src,src_axi);
hls_fast_corner(src_axi,dst_axi,src->height,src->width,20);
AXIvideo2IplImage(dst_axi,dst);
cvShowImage("hls_dst",dst);
cvSaveImage(OUTPUT_IMAGE,dst);
}
再test bench中添加测试文件test_1080p.bmp。就可以 点击仿真了。
然后结果保存在了工程路径下的:solution1\csim\build\result.bmp
结果展示:
最后感慨一下:世人总以为最大的敌人是他人,其实不然,面对繁华的世界,很难静下心来学习,唯有平静内心,熄灭心中的欲望才能提高学习效率。其实,你打败别人并不算真正的英雄,只有控制内心的各种欲望你才算是真英雄。共勉,加油!
-晓凡 2022年9月7日于南宁书