【xfopencv】在vivadoHLS上用xfopencv库编写灰度伪彩色图 彩虹图转换IP核

简介

首先其实彩虹图就是灰度图按照对应关系
灰度0-255 转换为RGB:红、橙、黄、绿、青、蓝
由于在xfopencv中的xf::Mat这个类型没有at方法,则我们需要编写一个读写Mat结构的方法。具体分析:

  1. 一个读灰度图像素值的方法
  2. 一个写RGB图像素值的方法
  3. 一个转换算法

具体分析

1.一个读灰度图像素值的方法

首先我们知道Mat存灰度就是一个数据单元存放一个对应的0-255的值,类型是uchar
那么我们的读取要从2维转换到1维上。因为在内存中Mat的存放是一维的,按行存储。
则我们用 x,y坐标访问这个数组就应该是

data[x+y*cols];

因为每行就是cols个值,cols相当于是宽度,按照 x+y*cols 我们就能够访问到 x列 y行的数据存放的值了。

具体方法:

uchar getPixel(Mat mat,int x,int y) {
    return mat.data[x + y * mat.cols];
}

2.一个写RGB图像素值的方法

RGB和灰度图有所不同,因为RGB图存储大小是灰度图的三倍。在内存中是BGR为一个块的大小。
一共是cols*rows个块。
这样我们用x y 去写入色值时,我们要分对B、G、R 哪一个块内色值写入。我们用 channle表示是对哪一个通道写值,则我们的方法可以表示为:

void setBGRPixel(Mat mat, int x, int y, uchar pixel,int channle) {
    mat.data[(x + y * mat.cols )*3 + channle ] = pixel;
}

3.一个转换算法

转换算法就很简单了 一个对每个图像像素点的遍历就行了。

void gray2Rainbow(Mat src,Mat out) {
    
    uchar tmp;
    for (int x = 0; x < src.cols; x++) {
        for (int y = 0; y < src.rows; y++) {
            tmp = getPixel(src, x, y);
            if (tmp <= 51) {
                setBGRPixel(out, x, y, 255, 0);
                setBGRPixel(out, x, y, tmp * 5, 1);
                setBGRPixel(out, x, y, 0, 2);
            }
            else if (tmp <= 102) {
                tmp -= 51;
                setBGRPixel(out, x, y, 255 - tmp * 5, 0);
                setBGRPixel(out, x, y, 255, 1);
                setBGRPixel(out, x, y, 0, 2);
            }
            else if (tmp < 153) {
                tmp -= 102;
                setBGRPixel(out, x, y, 0, 0);
                setBGRPixel(out, x, y, 255, 1);
                setBGRPixel(out, x, y, tmp * 5, 2);
            }
            else if (tmp < 204) {
                tmp -= 153;
                setBGRPixel(out, x, y, 0, 0);
                setBGRPixel(out, x, y, 255 - uchar(128.0 * tmp / 51.0 + 0.5), 1);
                setBGRPixel(out, x, y, 255, 2);
            }
            else {
                tmp -= 204;
                setBGRPixel(out, x, y, 0, 0);
                setBGRPixel(out, x, y, 127 - uchar(127.0 * tmp / 51.0 + 0.5), 1);
                setBGRPixel(out, x, y, 255, 2);
            }
        }
    }
}

最后的效果在这里插入图片描述

在这里插入图片描述

在xfopenCv上实现

由于,在xfopencv中 单通道图像的像素数据类型是ap_uint<8>,而RGB色值直接就是 ap_unit<24>来存储的,因此我们需要稍微修改一下我们的代码:

void gray2rainbow(GrayMat &mat1,ColorMat &mat2){
		ap_uint<8> pix_gray;
		ap_uint<24> pix_BGR;
		for (int x = 0; x <mat1.cols; x++) {
		for (int y = 0; y < mat1.rows; y++) {
			pix_gray = mat1.data[x+y*WIDTH];
			if(pix_gray < 51){
				mat2.data[x+y*WIDTH]=0x0000ff + 0x000100*pix_gray;
			}
			else if (pix_gray <= 102 && pix_gray > 51) {
				pix_gray=pix_gray-51;
				mat2.data[x+y*WIDTH]=0x00ffff-pix_gray*5;
			} else if(pix_gray < 153 && pix_gray>102){
				pix_gray=pix_gray-102;
				mat2.data[x+y*WIDTH]=0x00ff00+0x050000*pix_gray;
			}else if(pix_gray < 204 && pix_gray > 153 ){
				pix_gray=pix_gray-153;
				mat2.data[x+y*WIDTH]=0xffff00-0x000100*(ap_uint<24>(128.0*pix_gray/51.0+0.5));
			}else {
				pix_gray=pix_gray-204;
				mat2.data[x+y*WIDTH]=0xff8000-0x000100*(ap_uint<24>(127.0*pix_gray/51.0+0.5));
			}


	 }
 }
}

按照上诉算法即可得到下图的效果。
在这里插入图片描述
最后按照自定义的接口axis或者axiLite约束一下接口就可以综合生成IP核了。这里就不赘述啦。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值