2018-07-03 09:02:01 yunge812 阅读数 1149
  • 使用Snapdragon Profiler深度分析优化你的游戏

    Snapdragon Profiler提供四种分析模式,几十种硬件指标帮助分析调试应用性能以及渲染等问题。对于开发者尤其是和功耗、图形图像处理相关的开发者来说,Snapdragon Profiler将是您一个很好的帮手,它允许开发者分析CPU、GPU、DSP、memory、power、thermal和network数据等,从而帮助开发者根据这些数据进一步进行修改和优化。

    967 人正在学习 去看看 CSDN讲师

一、概述

系统整体框架。

1 通过TCP从上位机发送图片到DSP  

2 DSP将任务分配给8个核,进行图像处理(sobel运算)

3 每个核完成相应的任务之后,融合结果,通过TCP协议发送到上位机。

二、软件构成

主核主要包括两个进程。1 TCP进程  2 数据处理进程

从核包括一个进程。进行数据处理。

1   首先TCP进程进行数据接收,接收完毕之后,post mailbox1  告诉主核的数据处理进程数据接收完毕。

2   主核、从核进行messageQ操作。遵循原则 谁接收,谁创建;谁发送,谁打开的原则。主核给从核发送messageQ的信息主要是包括 各个从核对应处理的图片的首地址(红色虚线);从核给主核发送的messageQ主要是各个核处理之后的图片的首地址。(黄色虚线)

3  主核进行数据融合  然后发送mailbox2  将处理后的结果通过TCP发送到上位机。

 

程序下载地址:

https://download.csdn.net/download/yunge812/10517028

 

=======================================================================

最近新开的公众号,文章正在一篇篇的更新,

公众号名称:玩转电子世界

各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。

跟着阳光非宅男,一步步走进电子的世界。

关注之后回复 资料下载  关键词可以获得免费海量视频学习资料下载~~!

已共享的学习视频资料,共享资料正在不断更新中。。。

=======================================================================

2008-07-28 09:33:00 linglongyouzhi 阅读数 942
  • 使用Snapdragon Profiler深度分析优化你的游戏

    Snapdragon Profiler提供四种分析模式,几十种硬件指标帮助分析调试应用性能以及渲染等问题。对于开发者尤其是和功耗、图形图像处理相关的开发者来说,Snapdragon Profiler将是您一个很好的帮手,它允许开发者分析CPU、GPU、DSP、memory、power、thermal和network数据等,从而帮助开发者根据这些数据进一步进行修改和优化。

    967 人正在学习 去看看 CSDN讲师
 

用于海洋搜救的多片DSP图像处理识别系统的实现

[日期:2008-7-25] 来源:中电网  作者:烟台大学光电学院 毕 文 邵左文 许 兵 [字体: ]

 

引言

海上搜救服务是国家应急救援体系的重要组成部分,也是国家经济发展的重要保障。采用先进的搜索系统是提高搜救行动有效性的重要手段之一。通常情况下搜索系统采用雷达或者光电成像系统,因为光图像传感器具有很高的分辨率,在能见度理想的情况下,观测距离可达20~40km,但它的缺点就是在较大程度上依赖良好的天气及日照条件。而红外图像传感器具有穿透烟、雾、霾、雪等能力,可弥补这一不足,因此采用红外、可见光成像和DSP图像处理系统构成的光电搜索系统。

根据海洋搜救的性质,该系统应具备以下基本能力:

·较高的可疑目标检测能力;

·较高的海洋背景抗干扰能力;

·具有一定的目标识别和跟踪能力。

基于以上考虑,本文设计了由二片TMS320F2812和八片TMS320C6416T构成的图像处理系统。

系统指标要求

·可见光视频输入:CCIR/EIA或PAL/NTSC视频信号

·红外视频输入:CCIR/EIA

·视频输出:VGA或标准视频输出

·视频AD转换精度:12bit

·视频显示DA转换精度:10bit

·图像处理帧速率:大于30Hz

·可检测“目标”的最小象素数:3×3

系统方案

系统框图如图1所示。

采用TMS320F2812实现视频采集,通过XINTF接口与多片6416-HPI接口连接,实现图像数据传输。各6416采取流水工作模式,通过EMIFB接口输出处理后的图像数据,经过显示电路,由监视器显示输出图像。

系统采用可拓展结构,可根据实际需要确定6416图像处理单元数目。通常采用四个或八个6416图像处理单元。

系统软件对图像数据进行滤波和边缘检测,检测可疑目标并进行识别。

单视频输入时,可选择四个或八个6416图像处理单元构成图像处理机 。

双视频输入工作时序图如图2所示。每个视频通道拥有四个6416图像处理单元,分别采用流水工作模式,每片6416处理一幅图像的最大周期为4帧,两组的处理结果输出给图像显示模块处理。

系统硬件设计

硬件系统由三部分组成:视频采集电路、图像处理电路及显示电路。硬件设计总体框图如图3所示。

视频采集电路

基于2812-DSP的视频信号采集原理框图如图4所示,其中包括视频预处理模块和2812 模块。视频预处理模块包括Y/C分离、电平钳位、同步分离、幅度调整处理电路。2812-DSP片上A/D以12.5M的速度采集视频信号,达到了极限采样速率(采样间隔时间为80ns)。

Y/C分离、视频钳位、同步分离电路原理图见图5。

TMS320C6416T子模块

此模块是本系统处理部分的核心模块。按照通用性强、接口清晰简捷、资源引出最大化、兼顾构建多6416系统的设计思想来设计6416子模块,如图6所示。通过EMIFA接口扩展了两片4M×32bit SDRAM, 可一次读写64bit数据。

图像传输接口设计

图像数据通过2812-DSP-XINTF(16bit)/6416-DSP-HPI(32bit)接口传输,采用一片CPLD将2812-DSP两次输出结果拼接成32bit。优化2812-DSP-XINTF寄存器可使HPI接口传输速率达到最大。对XINTF寄存器的具体优化值见表1。

图像显示

采用VGA监视器显示图像处理结果。标准SVGA接口信号包括:行同步信号(VGA_Hs)、场同步信号(VGA_Vs)以及红、绿、蓝三路模拟信号。VGA所需的时序同步信号由CPLD产生,所需的模拟信号由视频D/A转换器ADV7123实现。显示接口电路框图如图7所示。

由CPLD对各个6416图像处理单元数据输出接口(EMIFB)总线进行总线仲裁,实现各个6416单元的图像数据分时输出。

两片采用“乒乓存取”工作方式的SRAM组成了图像数据缓冲区,每片SRAM存放一帧图像,由CPLD控制。

系统软件设计

系统软件流程图如图8所示。分为三个主要部分:图像预处理、可疑目标提取及目标识别。

图像预处理

图像滤波(多模板复合滤波算法)

对比常用的多种滤波算法,其共同特征是:某种滤波算法只对部分噪声有效;在较好地抑制噪声的同时,难以保持图像清晰度。而采用多模板复合滤波算法,可较好地解决这一问题,为边缘提取奠定了基础。

边缘检测(改进的sobel算子)

常用边缘检测算法受海面波纹的影响较为严重。相比之下,sobel算子效果较好,但也存在漏检边缘点的情况。本算法在传统sobel算子两个模板的基础上,增加了六个模板,用下述八个模板对每个像素分别进行运算,然后取其中最大值替代该像素的值。

这种改进的sobel算子使得边缘检测更加准确,但处理一帧图像的运算量较大。采用改进的sobel算子进行图像边缘检测处理后,将图像二值化。改进的sobel算子不但检测出了全部可疑目标,并且受海浪的影响较小。

可疑目标提取与跟踪

为减少运算数据量,采用二次标记的方法提取可疑目标:

·利用贴标签算法进行预标记,统计出物体数目并记录其所在位置;

·根据上位机提供的模板信息,提取可疑目标;

·进行二次标记,仅标记已提取的可疑目标;

·对提取出的可疑目标进行跟踪。

目标识别与跟踪

当提取的可疑目标(一般是指象素数较少的小目标)达到一定的象素数后,采用Hu不变矩特征对可疑目标进行目标识别。

对数字图像f(x,y),p+q阶矩(mpq)和中心矩(μpq)定义为

其中p和q是非负的整数。图像的(p+q)阶归一化的中心矩定义为:

利用二阶和三阶归一化的中心矩求出七个Hu不变矩组:

A(x,y)则为位置(x,y)处不变矩的相关值。取A值最大处对应的点作为匹配点。

由于不变矩描述的是图像的统计特性,满足对平移、伸缩、旋转等变化的不变性,因而广泛应用于图像识别等领域。该算法的不足之处是计算量大。而仅仅处理局部可疑目标区域图像数据的方法,可以大大减少数据运算量。对识别后的目标加框并跟踪。

结论

·成功实现了用于海洋搜救的多片DSP图像处理识别系统;

·成功实现了2812视频数据采集;

·系统硬件的可拓展性增强了系统的通用性;

·软件算法实际应用效果明显。

该系统(PCB板见图9)还可实现对搜救目标的被动测距、可见光和长波红外图像的双波段图像融合等功能。另外,系统的强大处理能力和存储空间,使其能在数字图像处理领域发挥更大作用。

2019-06-21 19:09:15 youbin2013 阅读数 158
  • 使用Snapdragon Profiler深度分析优化你的游戏

    Snapdragon Profiler提供四种分析模式,几十种硬件指标帮助分析调试应用性能以及渲染等问题。对于开发者尤其是和功耗、图形图像处理相关的开发者来说,Snapdragon Profiler将是您一个很好的帮手,它允许开发者分析CPU、GPU、DSP、memory、power、thermal和network数据等,从而帮助开发者根据这些数据进一步进行修改和优化。

    967 人正在学习 去看看 CSDN讲师

DSP图像数据流设计

DSP应用程序主要分为三个部分:采集、处理和显示。

第一,采集是指应用层调用DSP底层驱动函数user_read_upp_data()将一帧RGB565视频格式数据储存到指定位置,该函数通过UPP接口接收FPGA的YCBCR图像数据,并按照特定公式转换成RGB565图像放置在用户指定的数组里;

第二,处理是指将应用层按照实际需求将采集得到的图像进行处理,并在原图像上叠加字符、十字线、波门等信息;

第三,显示是指应用层调用DSP底层驱动函数user_write_video_buff()将处理后的图像送入显示缓冲区,DSP利用中断机制自动将缓存区的一个完整数据帧送给LCD屏(DSP6748平台)或通过UPP接口发给FPGA(DSP6655平台)。

具体流程图如下所示,需要说明的有以下几点:

  1. 数据采集和显示均由底层中断实现,不能或者占用很少主程序工作时间;
  2. 主程序只能和采集缓冲区、显示缓冲区进行交互,每次交互的图像数据量都是一帧;
  3. 采集缓冲区和显示缓冲区都采用3片buffer的结构形式,拿显示缓冲区举例,底层函数和主程序通过不同的接口指针去访问它,写入指针和读取指针不允许访问同一片buffer,防止数据帧出现半新半旧的情况,写入指针和读取指针都遵循buffer1         buffer2         buffer3         buffer1的访问流程;
  4. 当写入速度比读取速度快时,写入指针只有等读取指针访问完一块区域后,才能进行该区域的覆盖写入,如果有新数据来而读取指针又没访问完,则写入指针会停留在原区域重新写入,重新覆盖上一帧数据;
  5. 每次从采集缓冲区读取的数据帧都是上一次的,但如果主程序长时间未调用user_read_upp_data()函数,接下来读取的2个数据帧会和实时数据有长时间的时间差,后期要想办法优化;
  6. 如果主程序调用user_read_[A1] upp_data()函数太频繁,而采集函数又来不及更新缓冲区,则应用层会一直获得上一次已经取过的数据帧,直到下一帧数据接收完成;
  7. 每次更新显示缓冲区的数据,LCD都应在下一帧显示,但如果主程序调用user_write_video_buff()函数太频繁,LCD来不及刷新,那可能会造成部分数据帧丢失;

图1.1 DSP主程序流程图

 

1 数据采集:

1.1 数据传输方式

FPGA发送数据的方式:一帧图像数据大小为1440*576字节的大小,但是,FPGA端发送过程是分奇偶场分开发送数据的,奇场图像数据大小为1440*288,偶场图像数据大小为1440*288,先传偶场再传奇场,因此每次需要连续传输1440*288字节大小的数据。

DSP接收数据的方式:DSP通过UPP接口接收数据,实际上是通过内部UPP_DMA将UPP通道缓存中的接收到的数据以一个二维数组的形式搬移到DSP内部指定地址中(DDR3或DDR2),通过配置目标地址,传输行数,传输列数,传输偏移量来实现。

综上所述,一帧图像数据需要两次UPP来接收或发送。

1.2 数据同步

为了保证每次DSP数据的更新得到的都是最近的数据,那么得做好UPP传输的同步性,以及确保在时钟不稳时UPP发生错误时能够及时复位。交互中每次UPP数据发送完后FPGA会发送给DSP的一个GPIO(V中断)[A2] 中断来通知其上一场数据已经发送完毕,需要重新配置下一场数据的储存地址[A3] ,即使没有接收到1440*288个数据,也需要重置UPP接口,准备下次接收

具体交互是这样做的:FPGA在每次发送完UPP的数据后通过一个I/O口给DSP的GPIO BANK0PIN1发送一个上升沿脉冲,DSP将此引脚配置为上升沿触发中断模式。同时,通过GPIO BANK0PIN5做一个I/O口的Filed信号来区分数据是奇场数据还是偶场数据,如信号流程如图1.2所示。

图1.2 数据同步信号流程

V中断需要处理任务:

1,读取GPIO的Filed信号,并保存到gpio_f_flag中。

2,判别UPP DMA接收中断是否产生(判别UPP接收中断全局标识是否置1),若产生了接收中断,则清零接收中断标识位,并根据gpio_f_flag的值是1(高电平)或0(地电平)来区分是奇场数据还是偶场数据,以此来存放UPP数据到对应内存中;若没有产出接收中断,则说明此次UPP传输失败,则复位UPP外设,并重新配置UPP DMA参数。

3,配置好下一次UPP接收首地址并开启UPP接收通道。[A4] 

UPP中断需要处理任务:

根据UPP中断状态寄存器值判别是否发生了UPP接收窗口中断或发送窗口中断,若发生了,则将UPP接收中断全局标识置1,将UPP发送中断全局标识置1。

1.3 采集数据的转换和内存访问的切换

FPGA通过UPP发送给DSP的数据格式是YCRCB格式的,而且一帧分为了奇场和偶场,所以在处理数据之前得将接收到的数据分成Y场数据(720*576大小)和CRCB场数据(720*576大小)。各场的格式和数据转换如图1.3所示。先取一行偶场数据,将其中的Y0-Y719存入Y场的第一行,其中的CB0-CB359,CR0-CR359存入CBCR场的第一行;再取一行偶场数据,将其中的Y0-Y719存入Y场的第二行,其中的CB0-CB359,CR0-CR359存入CBCR场的第二行,以此类推,转换完一帧数据。

图1.3 各场数据格式

FPGA分两次给一帧图像,所以DSP一帧数据的BUFF设置为两个1440*288的缓存(UPP_BUFF_EVEN和UPP_BUFF_ODD),分别存储偶场数据和奇场数据。由于图像数据帧BUFF的写入和读出速度是不一样的因此需要设置6个BUFF数据帧来做写入和读取的切换,分别为UPP_BUFF1_EVEN,UPP_BUFF1_ODD,UPP_BUFF2_EVEN,UPP_BUFF2_ODD,UPP_BUFF3_EVEN,UPP_BUFF3_ODD。读取与写入的访问操作按以下顺序流程来操作(BUFF1->BUFF2->BUFF3->BUFF1->…)。

 

2013-07-11 19:47:33 saintfox001 阅读数 3829
  • 使用Snapdragon Profiler深度分析优化你的游戏

    Snapdragon Profiler提供四种分析模式,几十种硬件指标帮助分析调试应用性能以及渲染等问题。对于开发者尤其是和功耗、图形图像处理相关的开发者来说,Snapdragon Profiler将是您一个很好的帮手,它允许开发者分析CPU、GPU、DSP、memory、power、thermal和network数据等,从而帮助开发者根据这些数据进一步进行修改和优化。

    967 人正在学习 去看看 CSDN讲师

——(完整工程文件到我的资源下载)

Prewitt算子边缘检测

一、实验背景与意义

图像处理就是对信息加工以满足人的视觉心理或应用需求的方法。图像处理的方法有光学方法和电子学方法。从20世纪60年代起随着电子计算机和计算技术的不断提高和普及,数字图像处理进入了高速发展时期,而数字图像处理就是利用数字计算机或其它的硬件设备对图像信息转换而得到的电信号进行某些数学处理以提高图像的实用性。图像处理在遥感技术、医学领域、安全领域,工业生产中有着广泛的应用。其中在医学应用中的超声、核磁共振和CT等技术,安全领域和模式识别技术,工业中的无损检测技术尤其引人注目。计算机进行图像处理一般有两个目的:(1)生产更适合人观察和识别的图像。(2)希望能由计算机自动识别和理解图像。数字图像的边缘检测是图像分割、目标区域的识别、区域形状提取等图像分析领域的重要基础。图像处理分析的第一步往往就是边缘检测。物体的边缘是以图像的局部特征不连续的形状出现的,也就是指图像局部亮度变化最显著的部分,例如灰度值的突变、颜色的突变、纹理结构的突变等,同时物体的边缘也是不同的区域分界处。图像边缘有方向和幅度两个特性,通常沿边缘的走向灰度变化平缓,垂直于边缘走向的像素灰度变化剧烈。根据灰度变化的特点,图像边缘可分为阶跃型、房顶型和凸缘型。

边缘检测是图像处理、目标识别和计算机视觉等领域中最经典的研内容之一,已有较长的研究历史,边缘检测是所有基于边界分割方法的第一步。经典的边缘检测方法是对原始图像按像素的某邻域构造边缘检测算子。应用边缘检测的算法是基于边界的分割方法,常用的边缘检测算子有RobertsSobelKirschPrewitt以及Laplace等。其中Prewitt算子通过对图像进行八个方向的边缘检测,将其中方向响应最大的作为边缘幅度图像的边缘,且对噪声具有平滑作用。传统的边缘检测算子的噪声平滑能力和边缘定位能力是矛盾的。为了克服这个不足,正确地得到图像的边缘信息,已经提出了很多方法,其中边缘检测和边缘细化相结合可以有效地调节噪声平滑和边缘定位能力的矛盾。

二、基于Prewitt算法边缘检测的原理

Prewitt算子是一种一阶微分算子的边缘检测,利用像素点上下、左右邻点的灰度差,在边缘处达到极值检测边缘,去掉部分伪边缘,对噪声具有平滑作用。其原理是在图像空间利用两个方向模板与图像进行邻域卷积来完成的,这两个方向模板一个检测水平边缘,一个检测垂直边缘。

Prewitt边缘检测算法是一种类似Sobel边缘检测算法的边缘模板算法。Prewitt边缘检测算子并不把重点放在相邻的像素上,它对噪声具有平滑作用。采用3*3邻域可以避免在像素之间内插点上计算梯度。Prewitt算子也是一种梯度幅值,该算子包含两组3*3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以A代表原始图像,及分别代表经横向及纵向边缘检测的图像,其模板的卷积因子如下:

                    

  该算子包含两组3*3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。具体卷积算法如下:

   经典Prewitt算子认为:凡灰度新值大于或等于阈值的像素点都是边缘点。即选择适当的阈值T,若G(i,j)≥T,则(i,j)为边缘点,G(i,j)为边缘图像。这种判定是欠合理的,会造成边缘点的误判,因为许多噪声点的灰度值也很大,而且对于幅值较小的边缘点,其边缘反而丢失了。Prewitt算子利用像素点上下、左右邻点灰度差,在边缘处达到极值检测边缘。对噪声具有平滑作用,定位精度不够高。

三、算法编程步骤

1、为了对图像利用Prewitt算子进行边缘检测,编程主要步骤如下:

   输入:原灰度图像sourceIMG;

   输入:噪声强度range;

输出:加噪后的高斯噪声图像resultIMG;

Step 1:获取原图像的高rows与宽度cols;

Step 2:为输出图像resultIMG申请空间;

Step 3:for ( i=0; i< cols*(rows-2) - 2; i++)

         取3*3模板对应的原始像素;

         利用Prewitt垂直算子和水平算子计算相应差分并取绝对值输出像素=垂直方向差分+水平方向差分;

end for     

Step 4: 输出图像resultIMG,程序结束。

2、C语言代码如下:

/* ======================================================================== */

/*  Copyright 2006 by Wintech Digital System Technology Corp.               */

/*  All rights reserved. Property of Texas Instruments Incorporated.        */

/*  Restricted rights to use, duplicate or disclose this code are           */

/*  granted through contract.                                             */

/* ======================================================================== */

/*========  头文件引用===========*/

#include "stdio.h"

#include "math.h"

/*============= 工作变量定义======*/

unsigned char *pr_n;    //指针定义

unsigned char *pr_s;    //指针定义

//说明:定义数据存放变量

#pragma        DATA_SECTION(IMG,"data"); 

int  IMG[30000];

#pragma        DATA_SECTION(Noise_IMG,"data");

unsigned char  Noise_IMG[30000];

#pragma        DATA_SECTION(Smooth_IMG,"data");

unsigned char  Smooth_IMG[30000];

void  IMG_Smooth();

void IMG_sobel

(

    const unsigned char *restrict in,   /* Input image data   */

    unsigned char       *restrict out,  /* Output image data  */

    short cols, short rows              /* Image dimensions   */

);

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

//使用说明:

//   1. 本程序可以在Simulator下运动;

//   2. 程序编译、链接、加载成功后,先

//      执行File/data/load,将要进行颜色转换的图像数据从RGB_peppers96x128.dat 

//     (说明:*.dat格式,内部存放了某图像各像素的RGB颜色值)加载入数据存储器存储地址RGB_IMG中

//   3. 数据加载成功后,再Debug/Go Main, 一步一步运行程序

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

int CoefArray[9]={1,1,1,1,1,1,1,1,1};

/*================= 主程序 ================*/

main()

{   

long n;

int imgH,imgW;

    int *ptr;

    imgH=160;  //图像高与宽,因为数据文件中的图像是160X160像素的

    imgW=160; 

/*=========== 初始化 ==========*/

    //1 把图像数据从IMG中移到Noise_IMG数组中

    ptr=IMG;

    pr_n=Noise_IMG;

    for (n=0;n<imgH*imgW;n++)

       *pr_n++=*ptr++;

    //说明:在此暂停,可看到噪声图像 

//指针指向数组

pr_n=Noise_IMG;

pr_s=Smooth_IMG;

ptr=IMG;

    //2 调用子程序,进行彩色图像变换成灰度图像

    while (1)

    { 

       

       //IMG_Smooth(pr_n,pr_s,imgW,imgH);

       

       IMG_sobel(pr_n,pr_s,imgW,imgH);

       //说明:上面子程序执行后,在此暂停,可看平滑后的图像 

     }

    //说明:在此暂停,可看变换后的灰度图像 

}

/*============== 子程序 =============*/

void IMG_Smooth

(   unsigned char   *F,         /* 输入带有噪声的灰度图像      */

    unsigned char   *G,         /* 输出的平滑后的灰度图像      */

    int cols, int rows      /* 图像的宽度与高度            */

)

{    //定义局部变量

    unsigned char *ptr, *pp, *newpp;

    int tmpNum,x, y,k,m,temp;

    int tmp[9];

    //图像四周的像素不进衅交扔谠?

    for (x=0; x< cols -1; x++)  //处理第一行的像素

         G[x] = F[x];

      //处理最后一行的像素

      newpp  =  G + (rows-1)* cols;    //指针指向平滑图像

      pp     =  F+ (rows-1)* cols;     //指针指向噪声图像        

      for (x=0; x< cols -1; x++) 

          * newpp++ = * pp++;

      //处理最左边一列的像素

      newpp  =  G;    //指针指向平滑图像

      pp     =  F;     //指针指向噪声图像        

      for (y=0; y< rows -1; y++) 

      {

          *newpp = *pp;  

          newpp+=cols; pp+=cols;  //指针偏移到下一行像素的位置

      }

      //处理最右边一列的像素

      newpp  =  G+cols;    //指针指向平滑图像

      pp     =  F+cols;     //指针指向噪声图像        

      for (y=0; y< rows -1; y++) 

      {

         * newpp = * pp;  

         newpp+=cols; pp+=cols;  //指针偏移到下一行像素的位置

      }

      //采用中值滤波的方式对图像中的每个像素进行平滑

      for (y=1; y< rows -1; y++)

           for (x=1; x<cols -1; x++)

           {

                newpp   = G + y* cols +x;    //指针指向平滑图像

                pp      = F + y* cols +x;     //指针指向噪声图像        

                //累加第一排的3个像素的值

                ptr      =   pp-cols-1;             

                tmp[1]  =  (*ptr++)*CoefArray[0];

                tmp[2]=  (*ptr++)*CoefArray[1];

                tmp[3]=  (*ptr++)*CoefArray[2];

                //累加第二排的3个像素的值

                ptr      = pp-1;             

                tmp[4]=  (*ptr++)*CoefArray[3];

                tmp[5]=  (*ptr++)*CoefArray[4];

                tmp[6]=  (*ptr++)*CoefArray[5];

                //累加第三排的3个像素的值

                ptr      = pp+cols-1;             

                tmp[7]=  (*ptr++)*CoefArray[6];

                tmp[8]=  (*ptr++)*CoefArray[7];

                tmp[9]=  (*ptr++)*CoefArray[8];

               //累加的结果除以9

                tmpNum /=9;                      

               //检测数据是否溢出,且将平均值赋给平滑图像

               if (tmpNum > 255)

                    *newpp=255;

               else

                     

                    

            {

               for(k=0;k<7;k++)

                  for(m=k+1;m<8;m++)

                   {

             if ( tmp[m]>tmp[m+1] )

                  {

                 temp=tmp[m];

                  tmp[m]=tmp[m+1];

                 tmp[m+1]=temp;

                   }

               }    

             *newpp=tmp[4];

          

          }

       //取排序好的数组的中值赋给当前像素

      // *newpp=tmp[4];

      // newpp++;                                

       //pp++;                                                   

                                         

}

             

                 

} //程序结束

void IMG_sobel

(

    const unsigned char *restrict in,   /* Input image data   */

    unsigned char       *restrict out,  /* Output image data  */

    short cols, short rows              /* Image dimensions   */

)

{

    int H, O, V, i;

    int i00, i01, i02;

    int i10,      i12;

    int i20, i21, i22;

    int w = cols;

    /* -------------------------------------------------------------------- */

    /*  Iterate over entire image as a single, continuous raster line.      */

    /* -------------------------------------------------------------------- */

    for (i = 0; i < cols*(rows-2) - 2; i++)

    {

        /* ---------------------------------------------------------------- */

        /*  Read in the required 3x3 region from the input.                 */

        /* ---------------------------------------------------------------- */

        i00=in[i    ]; i01=in[i    +1]; i02=in[i    +2];

        i10=in[i+  w];                  i12=in[i+  w+2];

        i20=in[i+2*w]; i21=in[i+2*w+1]; i22=in[i+2*w+2];

        /* ---------------------------------------------------------------- */

        /*  Apply horizontal and vertical filter masks.  The final filter   */

        /*  output is the sum of the absolute values of these filters.      */

        /* ---------------------------------------------------------------- */

        H = -   i00 - 2*i01 -   i02 +

            +   i20 + 2*i21 +   i22;

        V = -   i00         +   i02

            - 2*i10         + 2*i12

            -   i20         +   i22;

        O = abs(H) + abs(V);

        /* ---------------------------------------------------------------- */

        /*  Clamp to 8-bit range.  The output is always positive due to     */

        /*  the absolute value, so we only need to check for overflow.      */

        /* ---------------------------------------------------------------- */

        if (O > 255) O = 255;

        else O = 0;

        /* ---------------------------------------------------------------- */

        /*  Store it.                                                       */

        /* ---------------------------------------------------------------- */

        out[i + 1] = O;

    }

}  

/* ======================================================================== */

/*             Copyright (c) 2012 LDX Digital System Technology Corp.   */

/*                         All Rights Reserved.                             */

/* ======================================================================== */

四、实验步骤与结果

1、设置CCS 2.2工作在软件仿真环境

(1)双击桌面上Setup CCS studio图标,运行CCS Setup,进入CCS设置窗口;

(2)在出现的窗口中,按下图所示的方法与顺序进行CCS设置;

  

(3)在弹出的窗口中点击“是”按键保存设置,退出CCS Setup,进入CCS开发环境,此时CCS被设置成Simulator仿真模式。

2、启动CCS。

双击桌面上CCS 2 (C6000)图标,运行CCS。

3、创建工程

(1)创建新的“BYJC”工程文件

   选择菜单“Project”的“New…”项

弹出如下对话框:


输入项目名称BYJC后,点击完成即可。

3先新建源程序窗口:点击“File/New/Source File”,输入源代码(上一步已给出)

点击“File/Save”,在弹出的保存对话框中,选择保存目录为“BYJC”,选择保存类型为“C Source Files”,保存源程序为main.c。

4. 运行程序,观察试验结果。

按如下方法观看试验结果:(1)编译、链接程序:执行菜单Project/Rebuild All,汇编结果在将汇编信息输出窗口中给出。编译后将在Bebug目录中产生一个ImgSmooth.out文件。

2)加载程序:执行File/Load Program,选择ImgSmooth.out并打开,即将可执行文件加载到DSP软件仿真器simulator中,此时CCS将自动打开一个反汇编窗口。

3)将RGB彩色图像的数据从dat文件读入到内存:执行File/data/load,将要进行颜色转换的图像数据从Gray_Lenna160x160.dat (说明:*.dat格式,内部存放了某图像各像素的RGB颜色值)文件中加载入到数据存储器,即在弹出的窗口中输入存储地址IMG与数据的长度,如下图所示。


4)运行程序:执行Debug/Run。为了便于观看试验前后的结果,可以在程序中设置断点,采用单步执行的方法运行程序。

5)显示平滑前的噪声图像:执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入RGB彩色图像三个通道数据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如下图所示。这样,原始的噪声图像如图1所示。




图1 原始图像

(6)显示平滑后的图像:执行View/Graph/Image,在弹出的对话框中选择颜色类型为RGB,并输入灰度图像据的地址,以及图像显示格式(显示几行、每行几像素)等内容,如下图所示。


图二为Prewitt算子边缘检测结果


五、分析与总结

  Prewitt算子:利用像素点上下、左右邻点灰度差,在边缘处达到极值检测边缘。对噪声具有平滑作用,但定位精度不够高。对噪声有抑制作用,抑制噪声的原理是通过像素平均,但是像素平均相当于对图像的低通滤波,所以Prewitt算子对边缘的定位不如Roberts算子。图像的峰值处对应着图像的边缘点,边缘位置和导数(微分)间具有一定对应关系,可通过微分进行边缘检测。无噪声时,可用Roberts算子;Prewitt和Sobel算子同时具有平均,即抑制噪声作用;对阶跃状边缘,Roberts得到的边缘宽度≥1个像素,Prewitt和Sobel算子得到的边缘宽度≥2个像素。


2018-07-03 17:38:36 yunge812 阅读数 803
  • 使用Snapdragon Profiler深度分析优化你的游戏

    Snapdragon Profiler提供四种分析模式,几十种硬件指标帮助分析调试应用性能以及渲染等问题。对于开发者尤其是和功耗、图形图像处理相关的开发者来说,Snapdragon Profiler将是您一个很好的帮手,它允许开发者分析CPU、GPU、DSP、memory、power、thermal和network数据等,从而帮助开发者根据这些数据进一步进行修改和优化。

    967 人正在学习 去看看 CSDN讲师

一、cfg文件

/* Create the stack Thread Task for our application. */
var tskSlaveThread       = Task.create("&slave_main");
tskSlaveThread.stackSize = 0x2000;
tskSlaveThread.priority  = 0x5;
tskSlaveThread.instance.name = "slave_main";

创建slave_main进程。

二、main函数

main函数很简单,只是打开IPC以及BIOS

三、slave_main进程

3.1 创建heapBuf

    /* Open the heap created by the other processor. Loop until opened. */    
    do {        
        status = HeapBufMP_open(IMAGE_PROCESSING_HEAP_NAME, &heapHandle); //"image_processing_heap"
        if (status < 0) { 
            Task_sleep(1);
        }
        //printf("HeapBufMP_open failed\n" );
    } while (status < 0);

3.2 创建messageQ( slave )

    /* Register this heap with MessageQ */    
    MessageQ_registerHeap((IHeap_Handle)heapHandle, IMAGE_PROCESSING_HEAPID);
    
    /* Create the local message queue */
    //从核创建MessageQ 根据MessageQ名字    主核在MessageQ_open打开   MessageQ名字在mc_process_init中设置
    h_receive_queue = MessageQ_create(receive_queue_name, NULL);
    if (h_receive_queue == NULL)
    {
        printf("MessageQ_create failed\n" );
		goto close_n_exit;
    }

3.3 接收messageQ( slave )

if (MessageQ_get(h_receive_queue, (MessageQ_Msg *)&p_msg, MessageQ_FOREVER) < 0) //接收MessageQ信息    通过p_msg结构体传输来   该结构体包含着 MessageQ头       核ID   图像处理参数
{
	printf("%s: This should not happen since timeout is forever\n", receive_queue_name);
	goto close_n_exit;
}

reply_queue_id = MessageQ_getReplyQueue(p_msg);  //获得回复队列的ID号 reply_queue_id    然后通过MessageQ_put发送出去
if (reply_queue_id == MessageQ_INVALIDMESSAGEQ)
{
      printf("receive_queue_name: Ignoring the message as reply queue is not set.\n", receive_queue_name);
      continue;
 }

3.4 sobel图像处理

process_rgb(&(p_msg->info));

p_msg->info是该核需要处理的图像的指针,处理之后的结果也在这里

3.5 发送messageQ( master)

        /*============== 向主核发送MessageQ信息===========*/
        if (MessageQ_put(reply_queue_id, (MessageQ_Msg)p_msg) < 0)
        {
            printf("%s: MessageQ_put had a failure error\n", receive_queue_name);
        }

        if (MultiProc_self() != 0)
        {
            Cache_inv(p_msg->info.scratch_buf[0], p_msg->info.scratch_buf_len[0], Cache_Type_ALL, FALSE);
            if (p_msg->info.scratch_buf[1])
            {
                Cache_inv(p_msg->info.scratch_buf[1], p_msg->info.scratch_buf_len[1], Cache_Type_ALL, FALSE); 
            }
            Cache_inv(p_msg, sizeof(process_message_t), Cache_Type_ALL, FALSE);
        }

至此,大功告成

程序下载连接:

https://download.csdn.net/download/yunge812/10517028

 

=======================================================================

最近新开的公众号,文章正在一篇篇的更新,

公众号名称:玩转电子世界

各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。

跟着阳光非宅男,一步步走进电子的世界。

关注之后回复  资料下载   关键词可以获得免费海量视频学习资料下载~~!

已共享的学习视频资料,共享资料正在不断更新中。。。

=======================================================================

 

 

 

没有更多推荐了,返回首页