vivado HLS实例----实现AWB

通过实现一个基础算法,熟悉vivadoHLS操作步骤,同时理解串行转并行的思维

文章目录

vivado HLS实例----实现AWB

一、AWB工程代码

1.ReadFile.h

        2.stream_awb_head.h

3.stream_awb_top.cpp

4.stream_awb_tb.cpp

二、添加Directive

三、实例工程分析

1.在for循环中加pipeline的同时,谨慎添加rewinding

2.串行转并行。

3.最后波形图

总结


vivado HLS实例----实现AWB

通过实现一个基础算法,熟悉vivadoHLS操作步骤,同时理解串行转并行的思维

一、AWB工程代码

1.ReadFile.h

#include<iostream>
#include<fstream>
#include <iomanip>
#include <ap_int.h>
#include <hls_stream.h>

using std::cerr;
using std::cout;
using std::setw;
using std::setfill;
using std::ifstream;
using namespace std;

//using namespace hls;
//typedef ap_uint<128> img_rgb;
//typedef stream<img_rgb> img_rgb_stream;
//hls::stream<my_uint128_t>
template <int N, typename Tn>
void ReadFilaeVec(char * fp, Tn &Img_rgb_stream)
{
	int i;
	int val;

	ifstream fp_strmi(fp);//fp is file mode
	if (!fp_strmi.is_open())
	{
		cerr << "Error!\n The file is not albe to open!\n";

	}
	else
	{

		for (i = 0; i < N; i++) // N= w*h*ch
		{
			fp_strmi >> val;
			//			*pOutBuf = val;
			Img_rgb_stream << val;
			//			pOutBuf++;

		}
	}
	fp_strmi.close();
	//cout << setw(60) << setfill('-') << '----'<<'\n';
	cout << "Read file successfully\n";
	//cout << setw(60) << setfill('-') << '-----'<<'\n';
}

2.stream_awb_head.h

#include <ap_int.h>
#include <ap_fixed.h>
#include <hls_stream.h>
using namespace hls;
typedef ap_uint<10> img_rgb;
typedef stream<img_rgb> stream_rgb;
//stream_rgb in_rgb_stream;
//stream_rgb out_rgb_stream;
#define IMAGE_WIDTH 100
#define IMAGE_HEIGHT 100
#define IMAGE_CHANNEL 3
#define IMAGE_WINSIZE (IMAGE_WIDTH * IMAGE_HEIGHT)
#define IMAGE_SIZE (IMAGE_WINSIZE * IMAGE_CHANNEL)
#define W  35
#define I  23
typedef ap_ufixed<W,I> img_cef;
//ap_ufixed<W,I> img_cef = 0;

//img_rgb M = img_rgb(255);
//img_cef T = (img_cef)(256);
//
//img_cef g_coefr = (img_cef)(1);
//img_cef g_coefg = (img_cef)(1);
//img_cef g_coefb = (img_cef)(1);

typedef unsigned char U8;
void balance_white_top(stream_rgb &in_rgb_stream, stream_rgb &out_rgb_stream,
		img_cef &g_kr,img_cef &g_kg,img_cef &g_kb);

//void balance_white_top(U8 img_r[IMAGE_WINSIZE], U8 img_g[IMAGE_WINSIZE], U8 img_b[IMAGE_WINSIZE]);

3.stream_awb_top.cpp

#include<fstream>
#include <iomanip>
#include<fstream>
#include<iostream>
#include <ap_fixed.h>
#include "stream_awb_head.h"
img_cef W_div = 1.0 / 3.0;

//img_cef coefr, coefg, coefb;
//static float W_div = 1.0 / 3.0;

img_rgb M = img_rgb(255);
img_cef T = (img_cef)(256);
img_cef g_coefr = (img_cef)(1);
img_cef g_coefg = (img_cef)(1);
img_cef g_coefb = (img_cef)(1);

void Addfunnction(img_rgb &val, img_cef coef, img_cef &K){
	img_cef valNew;
	//float K_img = 0;
	img_rgb val_rgb = val;

	K += val_rgb;
	//更新像素
	valNew = ((img_cef)(val_rgb) * coef);
	val = (valNew >= T) ? M : (img_rgb)(valNew);
}

void balance_white_top(
		stream_rgb &in_rgb_stream,
		stream_rgb &out_rgb_stream,
		img_cef &g_kr,img_cef &g_kg,img_cef &g_kb
		) {
	img_cef K = 0;
	img_cef Kr = 0;
	img_cef Kg = 0;
	img_cef Kb = 0;

//	img_cef coefr = g_coefr;
//	img_cef coefg = g_coefg;
//	img_cef coefb = g_coefb;
	//U8 valr, valg, valb;
	//img_rgb valr_r, valg_g, valb_b;
	//img_rgb valNewr, valNewg, valNewb;

	img_rgb valR;
	img_rgb valG;
	img_rgb valB;
	img_rgb img_r[IMAGE_WINSIZE] = { 0 };
	img_rgb img_g[IMAGE_WINSIZE] = { 0 };
	img_rgb img_b[IMAGE_WINSIZE] = { 0 };

//	g_kr = g_coefr;


loop1:
	for (int i = 0; i < IMAGE_WINSIZE; i++) {
		in_rgb_stream >> valR;
		in_rgb_stream >> valG;
		in_rgb_stream >> valB;

	block1:
		{
			Addfunnction(valR, g_coefr, Kr);
			Addfunnction(valG, g_coefg, Kg);
			Addfunnction(valB, g_coefb, Kb);
		}

		img_r[i] = valR;
		img_g[i] = valG;
		img_b[i] = valB;

		out_rgb_stream << img_r[i];
		out_rgb_stream << img_g[i];
		out_rgb_stream << img_b[i];


//		out_rgb_stream << valR;
//		out_rgb_stream << valG;
//		out_rgb_stream << valB;
	}
//		K = Kr + Kg + Kb;
//		K = K * W_div;
	K = (Kr + Kg + Kb) * W_div;

//block2:
//	{
	g_coefr = K / Kr;
	g_coefg = K / Kg;
	g_coefb = K / Kb;
	//}
//	g_coefr = coefr;
//	g_coefg = coefg;
//	g_coefb = coefb;

//	g_kr = g_coefr;
//	g_kg = g_coefg;
//	g_kb = g_coefb;

}

//第三版
//#include<fstream>
//#include <iomanip>
//#include<fstream>
//#include<iostream>
//
//#include "stream_awb_head.h"
//img_rgb M = 255;
//img_rgb T = 256;
//float coefr, coefg, coefb;
//static float W_div = 1.0 / 3.0;
//float g_coefr = 0;
//float g_coefg = 0;
//float g_coefb = 0;
//
//void Addfunnction(img_rgb *val, float coef, float *K){
//	img_rgb valNew;
//	//	U8 *p = img;
//	float K_img = 0;
loop2:
	for (int i = 0; i < IMAGE_WINSIZE; i++) {
		val = img[i];
//		//更新像素
//		valNew = *val * coef;
//		*val = (valNew >= T) ? M : valNew;
//
//		K_img += (float)(*val);
//		//out_rgb << img[i];
	}
//	//	//	return  K_img;
//	*K = K_img;
//}
//
//void balance_white_top(stream_rgb &in_rgb_stream, stream_rgb &out_rgb_stream) {
//	float K = 0;
//	float Kr = 0;
//	float Kg = 0;
//	float Kb = 0;
//
//	float coefr = g_coefr;
//	float coefg = g_coefg;
//	float coefb = g_coefb;
//	//U8 valr, valg, valb;
//	img_rgb valr_r, valg_g, valb_b;
//
//	img_rgb valNewr, valNewg, valNewb;
//
//
//	img_rgb valR;
//	img_rgb valG;
//	img_rgb valB;
//	img_rgb img_r[IMAGE_WINSIZE] = { 0 };
//	img_rgb img_g[IMAGE_WINSIZE] = { 0 };
//	img_rgb img_b[IMAGE_WINSIZE] = { 0 };
//
//loop1:
//	for (int i = 0; i < IMAGE_WINSIZE; i++) {
//		in_rgb_stream >> valR;
//		in_rgb_stream >> valG;
//		in_rgb_stream >> valB;
//
		img_r[i] = valR;
		img_g[i] = valG;
		img_b[i] = valB;
//
//
//	block1:
//		{
//		Addfunnction(&valR, coefr, &Kr);
//		Addfunnction(&valG, coefg, &Kg);
//		Addfunnction(&valB, coefb, &Kb);
//		}
//		out_rgb_stream << valR;
//		out_rgb_stream << valG;
//		out_rgb_stream << valB;
//
//		K = (Kr + Kg + Kb) * W_div;
//
//	block2:
//		{
//			coefr = K / Kr;
//			coefg = K / Kg;
//			coefb = K / Kb;
//		}
//		g_coefr = coefr;
//		g_coefg = coefg;
//		g_coefb = coefb;
//
//	}
//
//}

//第二版
//#include<fstream>
//#include <iomanip>
//#include<fstream>
//#include<iostream>
//
//#include "stream_awb_head.h"
//img_rgb M = 255;
//img_rgb T = 256;
//float coefr, coefg, coefb;
//static float W_div = 1.0 / 3.0;
//float g_coefr = 0;
//float g_coefg = 0;
//float g_coefb = 0;
//
//void Addfunnction(img_rgb img[IMAGE_WINSIZE], float coef, float *K){
//	img_rgb val;
//	img_rgb valNew;
//	//	U8 *p = img;
//	float K_img = 0;
//loop2:
//	for (int i = 0; i < IMAGE_WINSIZE; i++) {
//		val = img[i];
//		//更新像素
//		valNew = val * coef;
//		img[i] = (valNew >= T) ? M : valNew;
//
//		K_img += (float)(val);
//		//out_rgb << img[i];
//	}
//	//	//	return  K_img;
//	*K = K_img;
//}
//
//void balance_white_top(stream_rgb &in_rgb_stream, stream_rgb &out_rgb_stream) {
//	float K = 0;
//	float Kr = 0;
//	float Kg = 0;
//	float Kb = 0;
//
//	float coefr = g_coefr;
//	float coefg = g_coefg;
//	float coefb = g_coefb;
//	//U8 valr, valg, valb;
//	img_rgb valr_r, valg_g, valb_b;
//
//	img_rgb valNewr, valNewg, valNewb;
//
//
//	img_rgb valR;
//	img_rgb valG;
//	img_rgb valB;
//	img_rgb img_r[IMAGE_WINSIZE] = { 0 };
//	img_rgb img_g[IMAGE_WINSIZE] = { 0 };
//	img_rgb img_b[IMAGE_WINSIZE] = { 0 };
//
//loop1:
//	for (int i = 0; i < IMAGE_WINSIZE; i++) {
//		in_rgb_stream >> valR;
//		in_rgb_stream >> valG;
//		in_rgb_stream >> valB;
//
//		img_r[i] = valR;
//		img_g[i] = valG;
//		img_b[i] = valB;
//
//	}
//block1:
//	{
//	Addfunnction(img_r, coefr, &Kr);
//	Addfunnction(img_g, coefg, &Kg);
//	Addfunnction(img_b, coefb, &Kb);
//	}
//	K = (Kr + Kg + Kb) * W_div;
//
//block2:
//	{
//		coefr = K / Kr;
//		coefg = K / Kg;
//		coefb = K / Kb;
//	}
//	g_coefr = coefr;
//	g_coefg = coefg;
//	g_coefb = coefb;
//	loop3:
//	for (int i = 0; i < IMAGE_WINSIZE; i++) {
//		out_rgb_stream << img_r[i];
//		out_rgb_stream << img_g[i];
//		out_rgb_stream << img_b[i];
//	}
//
//}


//第一版
//void balance_white_top(stream_rgb &in_rgb_stream, stream_rgb &out_rgb_stream) {
//	float K = 0;
//	float Kr = 0;
//	float Kg = 0;
//	float Kb = 0;
//
//	float coefr = g_coefr;
//	float coefg = g_coefg;
//	float coefb = g_coefb;
//	//U8 valr, valg, valb;
//	img_rgb valr_r, valg_g, valb_b;
//
//	img_rgb valNewr, valNewg, valNewb;
//
//
//	img_rgb valR ;
//	img_rgb valG ;
//	img_rgb valB ;
	img_rgb img_r[IMAGE_WINSIZE] = { 0 };
	img_rgb img_g[IMAGE_WINSIZE] = { 0 };
	img_rgb img_b[IMAGE_WINSIZE] = { 0 };
//
//	loop1:
//	for (int i = 0; i < IMAGE_WINSIZE; i++) {
//		in_rgb_stream >> valR;
//		in_rgb_stream >> valG;
//		in_rgb_stream >> valB;
//
		Addfunnction(img_r, coefr, &Kr, &valr_r);
		Addfunnction(img_g, coefg, &Kg, &valg_g);
		Addfunnction(img_b, coefb, &Kb, &valb_b);
		img_r[i] = valR;
		img_g[i] = valG;
		img_b[i] = valB;
//
//		Kr += (float)(valR);
//		Kg += (float)(valG);
//		Kb += (float)(valB);
//
//		//更新像素
//		valNewr = valR * coefr;
//		valNewg = valG * coefg;
//		valNewb = valB * coefb;
//
//		valr_r = (valNewr >= T) ? M : valNewr;
//		valg_g = (valNewg >= T) ? M : valNewg;
//		valb_b = (valNewb >= T) ? M : valNewb;
		valr_r = (valNewr >= (img_rgb)(256)) ? (img_rgb)(255) : valNewr;
		valg_g = (valNewg >= (img_rgb)(256)) ? (img_rgb)(255) : valNewg;
		valb_b = (valNewb >= (img_rgb)(256)) ? (img_rgb)(255) : valNewb;
//
//		out_rgb_stream << valr_r;
//		out_rgb_stream << valg_g;
//		out_rgb_stream << valb_b;
		/*img_r[i] = valr_r;
		img_g[i] = valg_g;
		img_b[i] = valb_b;*/

//	}
//
//	K = (Kr + Kg + Kb) * W_div;
//
//	block2:
//	{
//		coefr = K / Kr;
//		coefg = K / Kg;
//		coefb = K / Kb;
//	}
//	g_coefr = coefr;
//	g_coefg = coefg;
//	g_coefb = coefb;
//
//}



//float Addfunnction(img_rgb val, float coef, float *K,img_rgb *val_l){
//
//	img_rgb valNew;
//	int K_img = 0;
//
loop:
	for (int i = 0; i < IMAGE_WINSIZE; i++) {
//		//val = img[i];
//		//更新像素
//		valNew = val * coef;
//		*val_l = (valNew >= T) ? M : valNew;
//		//out_rgb_stream << val_l;
//		K_img += (float)(val);
//	//}
//	//	return  K_img;
//	*K = K_img;
//}

4.stream_awb_tb.cpp

#include <typeinfo>
#include <iostream>
#include <iomanip>
#include "ReadFile.h"
#include "stream_awb_head.h"
//#include <ap_uint.h>
//#include <hls_stream.h>

//#include <opencv2/opencv.hpp>
//using namespace cv;


int main(){

	//U8 img[IMAGE_WINSIZE] = { 0 };

	//img_rgb Ref[IMAGE_WINSIZE] = { 0 };
	img_cef kr,kg,kb;


	char *fa = "E:/HLS/vsproj/AWB_formal/AWB_formal/3chn.txt";

	char *fp_ref = "E:/HLS/vsproj/AWB_formal/AWB_formal/3chn_ofter.txt";
	//char *fp_ref = "C:/Users/11693/Desktop/ref_file.txt";

	//	typedef ap_uint<128> img_rgb;
	stream_rgb in_img_rgb_stream;
	stream_rgb out_rgb_stream1;
	stream_rgb out_rgb_stream_full;
	stream_rgb refimg_rgb_stream;
	//	stream

	ReadFilaeVec<IMAGE_SIZE, stream_rgb>(fa, in_img_rgb_stream);
	ReadFilaeVec<IMAGE_SIZE, stream_rgb>(fp_ref, refimg_rgb_stream);

	unsigned int i = 0;
	unsigned int errcnt = 0;
	//第一帧
	balance_white_top(in_img_rgb_stream, out_rgb_stream1, kr, kg, kb);
	cout << "kr= " << kr << '\n';//探针
	cout << "kg= " << kg << '\n';//探针
	cout << "kb= " << kb << '\n';//探针

	//第二帧
	ReadFilaeVec<IMAGE_SIZE, stream_rgb>(fa, in_img_rgb_stream);
	balance_white_top(in_img_rgb_stream, out_rgb_stream_full, kr, kg, kb);
	cout << "kr= " << kr << '\n';//探针
	cout << "kg= " << kg << '\n';//探针
	cout << "kb= " << kb << '\n';//探针

	//typedef ap_uint<32> img_rgb;
	img_rgb Ref_val;
	img_rgb out_val;

	int Ref_val_U8;
	int out_val_U8;

	for (i = 0; i< IMAGE_SIZE; i++){
		refimg_rgb_stream >> Ref_val;
		out_rgb_stream_full >> out_val;
		Ref_val_U8 = (int)(Ref_val);
		out_val_U8 = (int)(out_val);
		if (abs(Ref_val_U8 - out_val_U8) > 1.0 ){
			errcnt++;
			cout << "i= " << i << " ----------";
//			cout << "img[1]= " << img[i] << " ----------";
			cout << "out_val= " << out_val << " ----------";
			cout << "Ref_val= " << Ref_val << '\n';
			break;
		}
	}
//	cout << "kr= " << kr << '\n'; //探针
//	cout << "kg= " << kg << '\n';//探针
//	cout << "kb= " << kb << '\n';//探针

	if (errcnt>0){
		cout << "Test with " << errcnt << " error";
//		system("pause");
		return 1;
	}
	else{
		cout << "Test Pass";
//		system("pause");
		return 0;
	}

}

二、添加Directive

在stream_awb_top.cpp文件中添加directive

loop1:
	for (int i = 0; i < IMAGE_WINSIZE; i++) {
#pragma HLS PIPELINE
		in_rgb_stream >> valR;
		in_rgb_stream >> valG;
		in_rgb_stream >> valB;

	block1:
		{
#pragma HLS ALLOCATION instances=Addfunction limit=3 function
			Addfunnction(valR, g_coefr, Kr);
			Addfunnction(valG, g_coefg, Kg);
			Addfunnction(valB, g_coefb, Kb);
		}

三、实例工程分析

1.在for循环中加pipeline的同时,谨慎添加rewinding

 添加rewinding会导致全局变量失效,g_coefr、g_coefg、g_coefb不会随着Addfunnction函数调用发生改变

2.串行转并行。

stream_awb_top.cpp文件中第一版、第二版、第三版都是串行

当前一帧的像素值使用上一帧的更新的g_coefr、g_coefg、g_coefb参数值。舍弃第一帧,只用第一帧的像素值只用于更新g_coefr、g_coefg、g_coefb参数值。

3.最后波形图


 

 

总结

  • HLS很重要的是串行转并行的思想
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值