ADI Blackfin DSP处理器-BF533的开发详解40:图像处理专题-GrayStretch 图像的灰度拉伸(含源码)

news2024/11/17 9:32:53

硬件准备

ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述

功能介绍

代码实现了图像的灰度拉伸,代码运行时,会通过文件系统打开工程文件根目下" …/ImageView"路径中的 testin.bmp文件,进行图像灰度拉伸处理后把图片保存到工程文件根目下" …/ImageView"路径中的 testout.bmp 文件,并且将处理后的图片显示到液晶屏上。

例子中的算法只支持尺寸为 480*272 的 24bit 的 bmp 图片,可以根据自己的需要自行调整。

代码使用说明

funct.c 中的 GrayStretch(const BMPIMAGE* img, float fA, float fB, float fC)
该函数是将读取的图像进行灰度拉伸处理。

BMPIMAGE * 图像结构体指针
float fA, float fB, float fC 灰度拉伸参数

在 main.c 文件中定义了一个#define LCD_VIEW_ENABLE 宏开关,如果不需要将处理后的图片显示在液晶屏上,只需将这个宏开关注释掉。

代码实验步骤

  1. 将工程文件根目下的 ImageView 文件夹内存放一个名为 testin.bmp 的图像文件,该文件尺寸为 480*272 的24bit 的 bmp 图片(默认已存一幅测试图片)。
  2. 打开工程文件 BF53x_GrayStretch.dpj,编译并运行代码
  3. 等待图像处理,处理完成之后会在液晶屏上显示处理后的图片,并在工程文件根目下的 ImageView 文件夹内生成一个处理后名为 testout.bmp 图片。

代码实验结果

1.液晶屏上显示处理后的图片。
2.在工程文件根目下的 ImageView 文件夹中查看处理后名为 testout.bmp 图片。

程序源码

bmp.c

#include<stdio.h>
#include “bmp.h”

/********************************************************

  • 函数名 : OpenBmpFile
  • 函数功能 : 以二进制形式打开计算机硬盘BMP图像文件
  • 函数参数 : const char * 图像文件名称
  •   			BMPIMAGE *			  图像结构体指针
    
  • 函数返回值 :FALSE 打开图像文件失败
  •   			TRUE	打开图像文件成功
    

/
int OpenBmpFile(const char
filename, BMPIMAGE
img) {
if((img->bmpfile = fopen(filename, “rb”)) == NULL)
{
printf(“open file is Failure\n\r”);
return FALSE;
}
return TRUE;
}
/
**

  • 函数名 : writeBmpFile
  • 函数功能 : 将二进制图像数据保存到计算机硬盘中
  • 函数参数 : const char * 图像文件名称
  •   			BMPIMAGE *			  图像结构体指针
    
  • 函数返回值 :FALSE 保存图像文件失败
  •   			TRUE	保存图像文件成功
    

******************************************************/
int writeBmpFile(const char
filename,const BMPIMAGE
img) {

FILE *fp;
unsigned int i,j;
unsigned char tempData, *pData;
unsigned int tempHeight;
unsigned int tempWidth;
tempHeight = img->infohead.BiHeight>>1;
tempWidth = img->infohead.BiWidth*3;
pData = img->imgbuf;
for(i = 0; i < img->imagesize; i = i + 3) {
	tempData = pData[i];
	pData[i] = pData[i + 2];
	pData[i + 2] = tempData;
}

for(i=0;i<tempHeight;i++)
{
	for(j=0;j<tempWidth;j++)
	{
		tempData = pData[(img->infohead.BiHeight-1-i)*tempWidth+j];
		pData[(img->infohead.BiHeight-1-i)*tempWidth+j] = pData[i*tempWidth+j];
		pData[i*tempWidth+j] = tempData;
	}
}

if((fp = fopen(filename, "wb")) == NULL)
{
	printf("seek file is Failure\n\r");
	return FALSE;
}	
fwrite(&img->filehead, 1, 2, fp);
fwrite(&img->filehead.bfSize, 1, 12, fp);
fwrite(&img->infohead, 1, 40, fp);
fwrite(img->imgbuf, 1, img->imagesize, fp);
fclose(fp);
fclose(img->bmpfile);
return TRUE;

}
/********************************************************

  • 函数名 : GetBmpHeader
  • 函数功能 : 读取BMP文件头
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :FALSE 读取BMP文件头失败
  •   			TRUE	读取BMP文件头成功
    

*******************************************************/
int GetBmpHeader(BMPIMAGE
img) {
unsigned char headbuffer[INFOHEADSIZE];
BMPFILEHEAD filehead = &img->filehead;
BMPINFOHEAD infohead = &img->infohead;
if (fread(headbuffer, 1, FILEHEADSIZE, img->bmpfile) != FILEHEADSIZE) {
return FALSE;
}
img->filehead.bfType[0] = headbuffer[0];
img->filehead.bfType[1] = headbuffer[1];
if (
(unsigned short )&filehead->bfType[0] != (0x4D42)) { / ‘BM’ /
printf(“file is not bmp\n\r”);
return FALSE; /
not bmp image
/
}
memcpy(&filehead->bfSize, &headbuffer[2], 4);
memcpy(&filehead->bfOffBits, &headbuffer[10], 4);
if(fseek(img->bmpfile, FILEHEADSIZE, SEEK_SET)) {
return FALSE;
}
if (fread(headbuffer, 1, INFOHEADSIZE, img->bmpfile) != INFOHEADSIZE) {
return FALSE;
}
memcpy(&infohead->BiSize, &headbuffer[0], 4);
memcpy(&infohead->BiWidth, &headbuffer[4], 4);
memcpy(&infohead->BiHeight, &headbuffer[8], 4);
memcpy(&infohead->BiPlanes, &headbuffer[12], 2);
memcpy(&infohead->BiBitCount, &headbuffer[14], 2);
memcpy(&infohead->BiCompression, &headbuffer[16], 4);
memcpy(&infohead->BiSizeImage, &headbuffer[20], 4);
memcpy(&infohead->BiXpelsPerMeter, &headbuffer[24], 4);
memcpy(&infohead->BiYpelsPerMeter, &headbuffer[28], 4);
memcpy(&infohead->BiClrUsed, &headbuffer[32], 4);
memcpy(&infohead->BiClrImportant, &headbuffer[36], 4);
if(infohead->BiPlanes != 1) {
return FALSE;
}
if(infohead->BiBitCount !=24) {
return FALSE;
}
if(infohead->BiCompression != BI_RGB) {
return FALSE;
}
GetImageSize(img);
return TRUE;
}

/********************************************************

  • 函数名 : GetImageSize
  • 函数功能 : 获取BMP文件大小
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :void
    ********************************************************/
    void GetImageSize(BMPIMAGE *img) {
    img->imagesize = img->infohead.BiHeight * WIDTHBYTES(img->infohead.BiWidth * img->infohead.BiBitCount);
    }

/********************************************************

  • 函数名 : ReadBMPData
  • 函数功能 : 读取BMP数据缓冲区
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :FALSE 读取BMP数据失败
  •   			TRUE	读取BMP数据成功
    

*******************************************************/
int ReadBMPData(const BMPIMAGE
img) {
unsigned int pitch = WIDTHBYTES(img->infohead.BiWidth * img->infohead.BiBitCount);
unsigned int readnum = 0;
int i, j, k;
unsigned char m_temp;
unsigned char *p_tmp, *p_tmp_cur;
unsigned char tempData, pData;
unsigned int index_data;
pData = img->imgbuf;
if(fseek(img->bmpfile, img->filehead.bfOffBits, SEEK_SET)) {
return FALSE;
}
p_tmp = NULL;
p_tmp = (unsigned char )malloc(pitch * img->infohead.BiHeight);
if(p_tmp != NULL) {
readnum = fread(p_tmp, 1, pitch * img->infohead.BiHeight, img->bmpfile);
p_tmp_cur = p_tmp;
for(i = img->infohead.BiHeight - 1; i >= 0; i–, p_tmp_cur += pitch) {
memcpy(&img->imgbuf[i
pitch], p_tmp_cur, pitch);
}
}
else {
for(i = img->infohead.BiHeight - 1; i >= 0; i–) {
readnum += fread(&img->imgbuf[i
pitch], 1, pitch, img->bmpfile);
}
}
for(index_data = 0; index_data < img->imagesize; index_data = index_data + 3) {
tempData = pData[index_data];
pData[index_data] = pData[index_data + 2];
pData[index_data + 2] = tempData;
}
if(p_tmp != NULL) {
free(p_tmp);
}
return (readnum == img->imagesize);
}

/********************************************************

  • 函数名 : Allocbuf
  • 函数功能 : 分配图像缓冲区
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :FALSE 分配图像缓冲区失败
  •   			TRUE	分配图像缓冲区成功
    

/
int Allocbuf(BMPIMAGE
img) {
if((img->imgbuf = malloc(img->imagesize)) == NULL)
return FALSE;
return TRUE;
}
/
*

  • 函数名 : Freebuf
  • 函数功能 : 释放图像缓冲区
  • 函数参数 : BMPIMAGE * 图像结构体指针
  • 函数返回值 :void
    *******************************************************/
    void Freebuf(BMPIMAGE
    img) {
    if(img->imgbuf != NULL)
    free(img->imgbuf);
    img->imgbuf = NULL;
    }

cpu.c

#include <cdefBF533.h>
#include “cpu.h”

void Init_Timers0(int dat)
{
*pTIMER0_CONFIG = 0x0019;
*pTIMER0_WIDTH = dat;
*pTIMER0_PERIOD = 2000;
}

void Enable_Timers0(void)
{
*pTIMER_ENABLE|= 0x0001;
asm(“ssync;”);
}

void Disable_Timers0(void)
{
*pTIMER_DISABLE |= 0x0001;
}

void Set_PLL(int pmsel,int pssel)
{
int new_PLL_CTL;
*pPLL_DIV = pssel;
asm(“ssync;”);
new_PLL_CTL = (pmsel & 0x3f) << 9;
*pSIC_IWR |= 0xffffffff;
if (new_PLL_CTL != *pPLL_CTL)
{
*pPLL_CTL = new_PLL_CTL;
asm(“ssync;”);
asm(“idle;”);
}
}

void Init_SDRAM(void)
{
*pEBIU_SDRRC = 0x00000817;
*pEBIU_SDBCTL = 0x00000013;
*pEBIU_SDGCTL = 0x0091998d;
ssync();
}

void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0x7bb07bb0;
*pEBIU_AMGCTL = 0x000f;
}

funct.c

#include “bmp.h”
#include “funct.h”

/********************************************************

  • 函数名 : GrayStretch
  • 函数功能 : 图像的灰度拉伸
  • 函数参数 : BMPIMAGE * 图像结构体指针
    float fA, float fB, float fC 拉伸参数
  • 函数返回值 :FALSE 处理失败
  •   			TRUE    处理成功
    

*******************************************************/
int GrayStretch(const BMPIMAGE
img, float fA, float fB, float fC)
{
int i,j,temp;
unsigned int pitch = WIDTHBYTES(img->infohead.BiWidthimg->infohead.BiBitCount);
for(i=0;iinfohead.BiHeight;i++)
{
for(j=0;j<pitch;j++)
{
temp = img->imgbuf[i
pitch+j];
if(temp<intX1)
img->imgbuf[ipitch+j] = temp(intY1/fA);
else if((temp>=intX1)&&(temp<=intX2))
img->imgbuf[ipitch+j] = ((intY2-intY1)/fB)(temp-intX1)+intY1;
else
img->imgbuf[ipitch+j] = ((255-intY2)/fC)(temp-intX2)+intY2;
}
}
return TRUE;
}

main.c

#include <cdefBF533.h>
#include “cpu.h”
#include “tftlcd.h”
#include “bmp.h”
#include “funct.h”

#define INFILEADDR “…/ImageView/testin.bmp”
#define OUTFILEADDR “…/ImageView/testout.bmp”
#define LCD_VIEW_ENABLE
/灰度拉伸参数/
/注意: intX1!=0,intX2!=255,intX1<intX2, intY1<intY2/
int intX1 = 60; //第一点X坐标
int intY1 = 30; //第一点Y坐标
int intX2 = 185; //第二点X坐标
int intY2 = 225; //第二点Y坐标

int main(void)
{
float fA,fB,fC;
fA = (float)intX1;
fB = (float)(intX2-intX1);
fC = (float)(255-intX2);
BMPIMAGE bmpimage;
Set_PLL(16,4);
Init_EBIU();
Init_SDRAM();
LCDBK_Disable();
if(!OpenBmpFile(INFILEADDR,&bmpimage))
return FALSE;
if(!GetBmpHeader(&bmpimage))
return FALSE;
if(!Allocbuf(&bmpimage))
return FALSE;
if(!ReadBMPData(&bmpimage))
return FALSE;

/* 图像的灰度拉伸		*/
if(!GrayStretch(&bmpimage, fA, fB, fC))
	return FALSE;	

#ifdef LCD_VIEW_ENABLE
Enable_Timers0();
RGB888_RGB565(&bmpimage,(void*)DisplayBuffer_565);
#endif

if(!writeBmpFile(OUTFILEADDR,&bmpimage))
	return FALSE;

#ifdef LCD_VIEW_ENABLE
InitDMA();
InitPPI();
InitTimer();
PPI_TMR_DMA_Enable();
LCD_Enable();
LCDBK_Enable();
Init_Timers0(1999);//1~1999 控制背光亮度
Enable_Timers0();
while(1);
#endif
}

lcd.c

#include <cdefBF533.h>
#include “tftlcd.h”
#include “cpu.h”

section(“sdram0_bank1”) unsigned char DisplayBuffer_565[272][1440] ;

void InitDMA(void)
{
int addr;
addr = &DisplayBuffer_565;
addr -= 1920;
*pDMA0_START_ADDR = addr;

*pDMA0_X_COUNT = 480;
*pDMA0_X_MODIFY = 2;
*pDMA0_Y_COUNT = 286;
*pDMA0_Y_MODIFY = 2;	
*pDMA0_CONFIG = 0x1034;

}

void InitPPI(void)
{
*pPPI_CONTROL = 0x781e;
*pPPI_DELAY = 0;
*pPPI_COUNT = 479;
*pPPI_FRAME = 286;
}

void InitTimer(void)
{
*pTIMER1_PERIOD = 525;
*pTIMER1_WIDTH = 41;
*pTIMER1_CONFIG = 0x00a9;
*pTIMER2_PERIOD = 150150;
*pTIMER2_WIDTH = 5250;
*pTIMER2_CONFIG = 0x00a9;
}

void PPI_TMR_DMA_Enable(void)
{
*pDMA0_CONFIG |= 0x1;
asm(“ssync;”);
InitTimer();
*pPPI_CONTROL |= 0x1;
asm(“ssync;”);
*pTIMER_ENABLE|= 0x0006;
asm(“ssync;”);
}

void PPI_TMR_DMAR_Disable(void)
{
*pDMA0_CONFIG &= (~0x1);
*pPPI_CONTROL &= (~0x1);
}

void RGB888_RGB565( BMPIMAGE* img, unsigned char *dst)
{
int i = 0;
int j = 0;

if (img->imagesize % 3 != 0)
{
    return;
}
for (i = 0; i < img->imagesize; i += 3)
{
     dst[j+1] = img->imgbuf[i+2] &0xf8; 			//B 
     dst[j+1] |= ((img->imgbuf[i+1]>>5) & 0x07);	//GH
     dst[j] = ((img->imgbuf[i+1]<<3) & 0xe0);  		//GL  
     dst[j] |= ((img->imgbuf[i]>>3) &0x1f); 		//R
    j += 2;  
    
}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82919.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

回归预测 | MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元多输入单输出回归预测

回归预测 | MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元多输入单输出回归预测 目录回归预测 | MATLAB实现WOA-GRU鲸鱼算法优化门控循环单元多输入单输出回归预测写在前面效果一览基本描述模型描述程序设计参考资料写在前面 程序获取 | 机器学习/深度学习程序获取方式&#xff0…

Django学习第一天记录

1.安装Django(Windows环境) 首先需要确定系统中存在python环境&#xff0c;当前&#xff0c;本机的python环境为python 3.6.6&#xff0c;可以使用命令python --version进行查看。 在python环境成功搭建的基础上&#xff0c;我们使用命令pip install django即可进行django环境…

虚拟现实解决方案,实现 VR 数智机房

如今&#xff0c;虚拟现实技术作为连接虚拟世界和现实世界的桥梁&#xff0c;正加速各领域应用形成新场景、新模式、新业态。 图扑软件基于自研可视化引擎 HT for Web 搭建的 VR 数据中心机房&#xff0c;是将数据中心的运营搬到 VR 虚拟场景。以数据中心实际场景为基础&#…

Chaos Vantage这款渲染器有多强,一起来了解一下

Chaos Vantage 是最老牌渲染器之一的VRay开发公司Chaos新开发的一款实时GPU渲染引擎&#xff0c;以前的名字是Project Lavina&#xff0c;首次在Siggraph 2018上作为技术预览展示&#xff0c;官方定位是“在完全光线追踪环境中探索大型3D场景的工具”。 与其他实时渲染解决方案…

头戴式耳机适不适合跑步、分享几款最适合跑步的耳机

激情的运动和美妙的音乐毫无疑问是绝妙的搭配&#xff0c;几乎每天都驰骋在田径场上的我&#xff0c;一直非常关注运动耳机&#xff0c;也有不少朋友找我推荐运动耳机。运动耳机的选择有很多&#xff0c;但是极度靠谱的产品却是真的很少&#xff01;如果你也不希望你在选购运动…

双十二大家都在买哪些书?这份书单请码住

双十二来啦&#xff0c;这一天也在提醒着我们这一年就要结束了。虽然距离上次买买买才过去不久&#xff0c;但是想读的书却在时刻增加。 这个双十二&#xff0c;依旧给大家推荐好书&#xff0c;根据近期搜索人气、销量排行、读者口碑整理了“计算机新书”“2022最受欢迎图书”“…

C#+SqlServer超市管理系统的设计与实现

目 录 1引言 1 1.1课题研究内容 1 2系统需求分析 1 2.1系统模块构建 1 2.1.1系统整体结构功能模块 1 2.1.2前、后台功能模块 2 3 数据库设计 3 3.1 E-R图和关系图 3 3.2数据库表设计 4 4系统实现 7 4.1 前台模块 7 4.2 后台模块 14 5 结果测试 24 5.1前台模块的测试 24 5.2后台…

教你制作GIF表情包,逐帧动画制作

我们经常看到很多著名的电影场景都被制作成GIF动画&#xff0c;非常有趣。下面2分钟教你制作GIF表情包&#xff0c;方法很简单&#xff0c;一起来学习吧&#xff01; 方法一&#xff1a;手机制作GIF 我们来看看如何在手机上制作GIF&#xff0c;您需要使用刷新视频编辑工具。打开…

南方农机杂志南方农机杂志社南方农机编辑部2022年第24期目录

南方论坛《南方农机》投稿&#xff1a;cnqikantg126.com 基于物联网的食用菌日光温室终端控制研究 崔玉萍;席雪琴; 8-1016 基于颜色统计的水果采摘机器人水果识别的研究 夏康利;何强; 11-16 基于MATLAB/GUI双作用椭圆轨道滚柱泵人机界面设计 陈舰; 17-20 电动自…

nodejs 引用 canvas报错:without installing the canvas npm package

Error: Not implemented:HTMLCanvasElement. prototype.getContext(without installing the canvas npm package) 试了node 14.19.1 和 node 16.15.0 两个版本的都不行&#xff0c;即使是npm install canvas 成功了&#xff0c;运行也会报错&#xff0c;困扰了好久&#xff0c;…

【Python百日进阶-数据分析】Day125 - plotly.express.scatter():散点图

文章目录一、散点图语法二、参数三、返回类型四、示例4.1 array_like 对象4.2 DataFrame 列4.3 使用列名设置大小和颜色4.4 颜色可以是连续的&#xff0c;也可以是离散的/分类的。4.5 所述symbol参数可以被映射到的列&#xff0c;可以使用多种符号。4.6 Dash 中的散点图4.7 散点…

零基础转行学python有必要去培训机构吗

Python语言&#xff0c;以其简单易学成为不少人学习编程语言的新方向。而市面上也出来了各种各样的python培训机构&#xff0c;不少人就有疑惑了&#xff0c;既然python语言简单易学&#xff0c;那么还有必要去培训机构系统学习吗&#xff1f;知了堂认为&#xff0c;如果你是想…

人工智能:声纹识别技术介绍

❤️作者主页&#xff1a;IT技术分享社区 ❤️作者简介&#xff1a;大家好,我是IT技术分享社区的博主&#xff0c;从事C#、Java开发九年&#xff0c;对数据库、C#、Java、前端、运维、电脑技巧等经验丰富。 ❤️个人荣誉&#xff1a; 数据库领域优质创作者&#x1f3c6;&#x…

使用gitee将本地资源上传

在编程时&#xff0c;写好本地文件以后我们可以使用gitee将写的东西上传到gitee官网上分享或者让我们自己可以随时查看&#xff0c;首先&#xff0c;我们需要下载git这个软件&#xff0c;在这里推荐使用电脑管家里面的软件管理下载 &#xff0c;软件图标如下&#xff1a; 1.生成…

自定义RBAC(4)

您好&#xff0c;我是湘王&#xff0c;这是我的CSDN博客&#xff0c;欢迎您来&#xff0c;欢迎您再来&#xff5e; 前面把RBAC的权限系统设计过程都讲清楚了&#xff0c;现在就来实现它。大致分这么几个步骤&#xff1a; 1、先定义出完整的权限系统表结构&#xff1b; 2、实现…

Sqlite 数据库操作(二)—— Sqlite常用API 及其使用方法

要使用sqlite数据库的API&#xff0c;需要满足两个条件&#xff1a; 安装sqlite3函数库 —— 终端输入 sudo apt-get install libsqlite3-dev 在程序中引入头文件 sqlite3.h —— #include <sqlite3.h>gcc编译时链接 sqlite3动态库 …

atompark:外贸工具-Atomic 6合一系列产品-Crack

Atomic Studio 邮件发件人Atomic Mail Sender 我们最畅销的电子邮件活动工具 邮件发件人 群发邮件发件人 使用我们内置的 SMTP 或您自己的&#xff01; 按姓名称呼收件人 移除退订者 电子邮件猎手 发现网站上的电子邮件地址 按关键字搜索 执行高速和准确的搜索 邮件验证器 …

Synchronized原理

Synchronized原理一、基本特点二、加锁工作过程 (锁升级/锁膨胀)2.1 偏向锁2.2 轻量级锁2.3 重量级锁三、锁消除四、锁粗化五、总结一、基本特点 结合锁策略&#xff0c;我们就可以总结出 Synchronized 具有以下特性(只考虑 JDK 1.8)&#xff1a; 开始时是乐观锁, 如果锁冲突…

数据结构.数组

数据结构.数组1.数组的概念和特点2.数组的定义和初始化3.数组的遍历4.数组的基本操作&#xff08;不多说 注解很详细&#xff09;5.操作的时间复杂度1.数组的概念和特点 数组就是一种容器&#xff08;装数据的&#xff09;&#xff0c;用来存储相同类型的数据值。 数组的特点…

RRT_star MATLAB

colormap 函数 创建栅格地图 clc clear close all%% 构建颜色MAP图 cmap [1 1 1; ... % 1-白色-空地0 0 0; ... % 2-黑色-静态障碍1 0 0; ... % 3-红色-动态障碍1 1 0;... % 4-黄色-起始点 1 0 1;... % 5-品红-目标点0 1 0…