ADI Blackfin DSP处理器-BF533的开发详解38:图像处理专题-Sobel 算子边缘检测(含源代码)

news2025/1/16 4:57:46

硬件准备

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

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述

功能介绍

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

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

代码使用说明

funct.c 中的 GradientSobel(BMPIMAGE* img)
该函数是将读取的图像进行 Sobel 算子边缘检测处理。
BMPIMAGE * 图像结构体指针

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

代码调试步骤

  1. 将工程文件根目下的 ImageView 文件夹内存放一个名为 testin.bmp 的图像文件,该文件尺寸为 480*272 的24bit 的 bmp 图片(默认已存一幅测试图片)。
  2. 打开工程文件 BF53x_GradientSobel.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;
}

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

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

相关文章

Java集合和常见数据结构以及泛型

Java集合和常见数据结构以及泛型集合概述Collection集合的体系特点Collection集合常用APICollection集合的遍历方式方法一&#xff1a;迭代器方法二&#xff1a;foreach/增强for循环方法三&#xff1a;lambda表达式Collection集合存储自定义类型的对象常见数据结构数据结构概述…

PDF格式如何转成Excel?这篇文章教会你如何转换

不知道在日常的办公中&#xff0c;大家有没有碰到过这样一个问题&#xff1a;当领导给你发个PDF文件后&#xff0c;要求你尽快的将PDF文件中的表格数据进行修改&#xff0c;但当你把PDF转换成Excel格式后&#xff0c;发现转换后的文件排版格式错乱的。可是截止时间的压迫和乱七…

[附源码]Python计算机毕业设计大学生日常行为评分管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

Python输出文字改变颜色

# Python输出文字改变颜色的方法 一、使用注释性输出 &#xff08;一&#xff09;、基本语法 \033[显示方式; 前景色; 背景色m******\033[0m 显示方式、前景色、背景色都为可选参数&#xff0c;选择自己需要的即可&#xff0c;而且顺序可变非固定&#xff0c;但建议按照默认顺…

Openlayers 自定义投影坐标系数据转换以及在线转换工具

Openlayers 自定义投影坐标系数据转换以及在线转换工具OpenLayers 教程查看 EPSG 码和定义Openlayers 自定义投影坐标系数据转换以及在线转换工具在线示例OpenLayers 教程 工作中经常会遇到转换坐标的情况&#xff0c;一般都会写代码搞定&#xff0c;但是有时候只需要查看一下…

web前端期末大作业:基于HTML+CSS+JavaScript汽车租赁网站(47页)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

ELK 企业级日志分析系统

一、ELK 概述 1、ELK 简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用户对日志的查询、排序、统计需求。 ●ElasticSearch&#xff1a;是基于Lucene&#xff08;一个全文检…

[附源码]Python计算机毕业设计Django安防管理平台

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

CleanMyMacX软件怎么样?实际使用效果功能讲解

如果你也对MAC系统的优化和文件管理摸不清头脑&#xff0c;不知道该如何清理垃圾和缓存文件。那你可以试试我最近发现的这款软件——CleanMyMac X。 这是一款MAC OS的老牌清理软件&#xff0c;集系统的清理、提速、保护和软件的卸载于一体,由知名软件开发商MACPaw开发&#xf…

未来五年,人类和数字化劳动力混合的员工队伍将变得非常普遍

从机器管家安德鲁&#xff0c;到钢铁侠的贾维斯&#xff0c;无论是实体智能机器人&#xff0c;还是人工智能系统&#xff0c;人们对于机器人助手的想象从未停止过。 虽然&#xff0c;人类和机器人助手一起工作&#xff0c;听上去很科幻&#xff0c;但这一情况如今已比想象的更…

SpringBoot整合邮件服务(QQ邮箱)

文章目录SpringBoot整合邮件服务配置选择账户点击开启SMTP服务&#xff1a;发送短信&#xff1a;发送完&#xff0c;点击我已发送&#xff0c;然后得到密码&#xff1a;POM依赖&#xff1a;application.ymlJava集成EmailService在controller里定义接口&#xff1a;在业务实现层…

继承——C++第二大特性

目录 一、概念及定义 1、概念 2、定义 &#xff08;2&#xff09;方式 &#xff08;3&#xff09;继承基类成员访问方式的变化 二、父类子类赋值转换 三、继承中的作用域 四、派生类的默认成员函数 六、继承与静态成员 七、复杂的菱形继承及菱形虚拟继承 八、归纳 一、…

C语言——每周刷题题集(第一周)

前言 做题可以更好地巩固所学知识&#xff0c;并加深对于知识点的理解。下面题目均来自牛客网入门编程练习题。 第一题: BC8 十六进制转十进制 描述&#xff1a; BoBo写了一个十六进制整数ABCDEF&#xff0c;他问KiKi对应的十进制整数是多少。 输入描述&#xff1a; 无 …

基于自注意力的生成对抗归因网络的交通流缺失数据修复

文章信息《Missing Data Repairs for Traffic Flow With Self-Attention Generative Adversarial Imputation Net》是2022年7月发表在期刊IEEE TRANSACTIONS ON INTELLIGENT TRANSPORTA TION SYSTEMS上的一篇文章。摘要随着传感器技术的快速发展&#xff0c;由多个空间分布的传…

2023我为什么建议你学Python?

前言 最近有一位读者准备实习开始找工作&#xff0c;来跟我交流他目前找工作遇到的一些情况&#xff1a; “我被找工作弄得满头包&#xff0c;觉得好像自己学的专业很没有市场&#xff0c;也没有很好的大公司背书&#xff0c;根本没有和 HR 谈薪资的底气。 他最近撒简历发现…

Java IO流

一、IO的概念 Java IO&#xff1a;Java IO即Java 输入输出系统。不管我们编写何种应用&#xff0c;都难免和各种输入输出相关的媒介打交道&#xff0c;其实和媒介进行IO的过程是十分复杂的&#xff0c;这要考虑的因素特别多&#xff0c;比如我们要考虑和哪种媒介进行IO&#x…

react进阶用法完全指南

React调用回调函数&#xff0c;正确设置this指向的三种方法 通过bind this.increment this.increment.bind(this);通过箭头函数 <button onClick{this.multi}>点我*10</button> multi () > {this.setState({count: this.state.count * 10}) }箭头函数包裹 …

[附源码]Python计算机毕业设计大学生学科竞赛管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

【特征选择】时变正弦和 V 形传递函数 (BMPA-TVSinV) 的新型二元海洋捕食者算法附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

CSC7136B

CSC7136B是一款高效率低待机功耗原边反馈小功率 电源 AC/DC 驱动 电路&#xff0c;无 需光耦、TL431 及相关器件。CSC7136B采用开关频率调制和初级电流峰值振幅&#xff08; FM 和 AM &#xff09;多模式工作技术&#xff0c;保证了全负载和线性范围内的较高的转换效率。恒压模…