发新帖本帖赏金 5.00元(功能说明)我要提问
返回列表
打印
[DSP编程]

我的5509A之路

[复制链接]
楼主: wopt
手机看帖
扫描二维码
随时随地手机跟帖
41
wopt|  楼主 | 2015-4-6 11:01 | 只看该作者 回帖奖励 |倒序浏览
本帖最后由 wopt 于 2015-4-9 21:16 编辑

3.7 LMS
Least mean-square algorithm,最小均方算法。由Widrow等人在1975年提出。
定义
u(n):输入向量,或称为训练样本
w(n):权值向量
e(n):偏差
d(n):期望响应

d^(n):对期望响应d(n)的估计
n:迭代次数

µ:步长因子或步长参数。

LMS算法:
步骤1
初始化
迭代次数:n = 0
权向量:w(0) = 0
估计误差:e(0) = d(0) - d^(0) = d(0)
输入向量:u(0) = [u(0)  0 ……  0]T

步骤2:对 n = 0, 1 , 2…
权向量的更新:w(n + 1) = w(n) + µ * u(n)  * e*(n)
期望信号的估计:d^(n + 1) =  w(n + 1) * u(n + 1)
估计误差:e(n + 1) = d(n + 1) - d^(n + 1)

步骤3: n = n + 1,重复步骤2
先来一个简单的例子,熟悉下lms算法。Matlab上菜。
clc; clear all;
%% lms
N = 2048;                               % 信号的取样点数
M = 10;                                  % 抽头的个数
iter = N;                               % 迭代次数
t = 1 : N;
s = 5 * sin(2 * pi * 0.01 * t);         % 源信号
x = s + 0.5 * randn(1, N);              % 输入信号
x = x';
d = s';                                 % 期望信号
e = zeros(iter, 1);            
w = zeros(M, iter);   

rho_max = max(eig(x * x'));   % 输入信号相关矩阵的最大特征值
mu = rand(1) * (2 / rho_max)   ;   % 收敛因子 0 < mu < 2/rho

for n = M + 1 : iter -1               
    w( :, n + 1) = w( :, n) + mu * x(n - 1 : -1 : n - M) * conj(e(n));
    y(n + 1) = w( :, n + 1)' * x(n : -1 : n - M + 1);
    e(n + 1) = d(n + 1, : ) - y(n + 1);
end

%% 画输入输出信号以及输出信号和预期输出信号的误差
figure(1);
subplot(2, 1, 1);
plot(t, x);
grid;
title('输入信号');
xlabel('样点数');
ylabel('幅值');

subplot(2,1,2);
plot(t, y);
grid;
title('输出信号');
xlabel('样点数');
ylabel('幅值');

% 绘制自适应滤波器输出信号,预期输出信号和两者的误差
figure(2)
subplot(3, 1, 1);
plot(t, d);
grid;
title('预期输出');
xlabel('样点数');
ylabel('幅值');

subplot(3, 1, 2);
plot(t, y);
grid;
title('自适应滤波器输出');
xlabel('样点数');
ylabel('幅值');

subplot(3, 1, 3);
plot(t, e);
grid;
title('误差');
xlabel('样点数');
ylabel('幅值');

在来一个难一点的。引用《现代数字信号处理及其应用》—何子述、夏威  课后的一个仿真题。
clc; clear all;
%% 产生512点输入序列
M = 2;                                               % AR 阶数
N = 512;                                             % 样本数
trials = 100;                                        % 试验次数
a1 = -0.975;                                         % AR parameter
a2 = 0.95;
var = 0.0731;                                        % 噪声方差
v = 0 + sqrt(var).* randn(N, 1);                     % 产生v(n)
u0 = [0, 0];                                         % u(0)初始化
a = [1 a1 a2];
b = 1;
zi = filtic(b, a, u0);             % 初始化滤波器 直接II型
[u, zf] = filter(b, a, v, zi);     % 产生观测信号u(n)

%% 用LMS算法计算w1和w2

mu1 = 0.05;
mu2 = 0.005;
w1 = zeros(M, N);                                   % 初始化权向量
w2 = zeros(M, N);
w1_trials = zeros(M, N, trials);
w2_trials = zeros(M, N, trials);
                       
e1 = zeros(N, 1);                                   % 初始化误差
e2 = zeros(N, 1);
e1_trials = zeros(N, 1, trials);  
e2_trials = zeros(N, 1, trials);

d1 = zeros(N, 1);                                   % 初始化期望响应
d2 = zeros(N, 1);

wopt = zeros(2, trials);
Jmin = zeros(1, trials);   
sum_eig = zeros(1, trials);

for i = 1 : trials
     v = 0 + sqrt(var).* randn(N, 1);
     zi = filtic(b, a, u0);              
     [u, zf] = filter(b, a, v, zi);      
     
     uu = zeros(M, N - M + 1);                       
     for k = 1 : (N - M + 1)
         uu( :, k) = u(k + M - 1 : -1 : k).';         
     end
     R = uu * uu' / (N - M + 1);                     % u(n)自相关矩阵
     p = sum(uu(:, 1 : N - M) * diag(u(3 : N)), 2) / (N - M);
     [v, d] = eig(R);
     wopt( :, i) = inv(R) * p;
     Jmin(i)   = R(1, 1) - p' * wopt( :, i);         % Jmin
     sum_eig(i) = d(1, 1) + d(2, 2);                 % 特征值之和
   
     for n = 3 : N -1
        w1( :, n + 1) = w1( :, n) + mu1 * u(n - 1 : -1 : n - 2, :) * conj(e1(n));
        d1(n + 1) = w1( :, n + 1)' * u(n : -1 : n - 1, : );
        e1(n + 1) = u(n + 1, : ) - d1(n + 1);
        
        w2( :, n + 1) = w2( :, n) + mu2 * u(n - 1 : -1 : n - 2, :) * conj(e2(n));
        d2(n + 1) = w2( :, n + 1)' * u(n : -1 : n - 1, : );
        e2(n + 1) = u(n + 1, : ) - d2(n + 1);
     end
     w1_trials ( :, :, i) = w1;
     e1_trials ( :, :, i) = e1 .* conj(e1);
     
     w2_trials ( :, :, i) = w2;
     e2_trials ( :, :, i) = e2 .* conj(e2);
end
w1_trials_ave = sum(w1_trials , 3) ./ trials;
e1_trials_ave = sum(e1_trials , 3) ./ trials;
w2_trials_ave = sum(w2_trials , 3) ./ trials;
e2_trials_ave = sum(e2_trials , 3) ./ trials;

sJmin = sum(Jmin) / trials;                         % 维纳误差 平均
Jex1 = e1_trials_ave - sJmin;                       % 剩余均方误差
Jex2 = e2_trials_ave - sJmin;                       % 剩余均方误差
sum_eig_trials = sum(sum_eig) / trials;             % 平均特征值之和
Jexfin1 = mu1 * sJmin * (sum_eig_trials / (2 - mu1 * sum_eig_trials));
Jexfin2 = mu2 * sJmin * (sum_eig_trials / (2 - mu2 * sum_eig_trials));
M1 = Jexfin1 / sJmin;                               % 失调参数
M2 = Jexfin2 / sJmin;                               % 失调参数
disp(M1);
disp(M2);
%% 画滤波器的权向量和学习曲线
figure(1);                                  % 画权值迭代过程
plot(w1(1, :), 'b');                        % 单次估计 w1
hold on
plot(w1(2, :), 'r');
hold on
plot(w1_trials_ave(1, :), 'b');             % 估计平均 w1
hold on
plot(w1_trials_ave(2, :), 'r');
xlabel('迭代次数n');
ylabel('抽头权值');
title('滤波器权系数的更新过程 \mu=0.05');

figure(2);                                  % 画权值迭代过程
plot(w2(1, :), 'b');                        % 单次估计 w2
hold on
plot(w2(2, :), 'r');
hold on
plot(w2_trials_ave(1, :), 'b');             % 估计平均 w2
hold on
plot(w2_trials_ave(2, :), 'r');
xlabel('迭代次数n');
ylabel('抽头权值');
title('滤波器权系数的更新过程 \mu=0.005');

figure(3);                                  % 画学习曲线
plot(Jex1, 'b');                            % 画mu1时的学习曲线
hold on
plot(Jex2, 'r');                            % 画mu2时的学习曲线
hold on
axis([0,550,0,1]);
xlabel('迭代次数n');
ylabel('MSE');
title('LMS算法的学习曲线');
legend('\mu1=0.05', '\mu2=0.005');

接下来在看看开发板附赠程序LMS的代码
#include"math.h"

#define PI 3.1415926
#define COEFFNUMBER 16
#define INPUTNUMBER 1024

int FIRLMS(int *nx,float *nh,int nError,int nCoeffNumber);

float h[COEFFNUMBER],fU;
int xx[INPUTNUMBER],rr[INPUTNUMBER],wc[INPUTNUMBER];

main()
{
        int i,nLastOutput;
        
        nLastOutput=0;
        fU=0.0005;
        for ( i=0;i<COEFFNUMBER;i++ )        h[i]=0;
        for ( i=0;i<INPUTNUMBER;i++ )
        {
                xx[i]=256*sin(i*2*PI/34);
                rr[i]=wc[i]=0;
        }
        for ( i=COEFFNUMBER+1;i<INPUTNUMBER;i++ )
        {
                nLastOutput=FIRLMS(xx+i,h,nLastOutput-xx[i-1],COEFFNUMBER);        // break point
                rr[i]=nLastOutput;
                wc[i]=rr[i]-xx[i];
        }
        exit(0);
}

int FIRLMS(int *nx,float *nh,int nError,int nCoeffNumber)
{
        int i,r;
        float fWork;
        
        r=0;
        for ( i=0;i<nCoeffNumber;i++ )
        {
                fWork=nx[i]*nError*fU;
                nh[i]+=fWork;
                r+=(nx[i-i]*nh[i]);
        }
        r/=128;
        return r;
}
DSPLIB库中提供了LMS函数。

// LMS FIR (delayed version)
ushort dlms (DATA *x, DATA *h, DATA *r, DATA *des,DATA *dbuffer, DATA step, ushort nh, ushort nx)
// Adaptive delayed LMS filter (fast implemented)
ushort oflag = dlmsfast (DATA *x, DATA *h, DATA *r, DATA*des, DATA *dbuffer, DATA step, ushort nh, ushort nx)



使用特权

评论回复
42
wopt|  楼主 | 2015-4-9 21:18 | 只看该作者
本帖最后由 wopt 于 2015-6-11 10:55 编辑

3.8 kalman
推荐一篇关于kalman的**。  Kalman滤波器从原理到实现   
http://xiahouzuoxin.github.io/notes/html/Kalman%E6%BB%A4%E6%B3%A2%E5%99%A8%E4%BB%8E%E5%8E%9F%E7%90%86%E5%88%B0%E5%AE%9E%E7%8E%B0.html

以下内容均参考清华大学出版社《现代数字信号处理及其应用》——何子述等

      卡尔曼滤波是一种高效率的递归滤波器(自回归滤波器), 它能够从一系列的不完全及包含噪声的测量中,估计动态系统的状态。斯坦利·施密特(Stanley Schmidt)首次实现了卡尔曼滤波器。卡尔曼在NASA埃姆斯研究中心访问时,发现他的方法对于解决阿波罗计划的轨道预测很有用,后来阿波罗飞船的导航电脑使用了这种滤波器。关于这种滤波器的论文由Swerling(1958),Kalman(1960)与Kalman and Bucy(1961)发表。

特点:收敛速度快(比lms快),存储量小
       卡尔曼滤波不用横向滤波器对观测数据进行滤波,而是将观测数据看成是某个用状态变量方法描述的系统的输出,通过引入新息过程的概念,采用迭代方法直接利用观测数据进行运算,可得到原系统状态向量的估计。卡尔曼滤波器不仅适用于平稳随机过程,也同样适合于非平稳随机过程。

系统状态方程和观测方程:
1、状态方程(过程方程)
     x(n) = F(n, n - 1) x(n - 1) + L(n, n - 1)v1(n - 1)
  • 状态向量: x(n)
  • 状态转移矩阵:F(n, n - 1)
  • 状态噪声输入矩阵:L(n, n - 1)
  • 系统状态噪声:v1(n - 1)

2、观测方程(量测方程)
     z(n) = C(n)x(n) + v2(n)
  • 观测向量:z(n)
  • 观察矩阵:C(n)
  • 观察噪声:v2(n)


卡尔曼滤波计算步骤
已知条件
状态方程:x(n) = F(n, n - 1) x(n - 1) + L(n, n - 1)v1(n - 1)
观测方程:z(n) = C(n)x(n) + v2(n)
初始条件:在初始时刻,由于不能精确知道状态方程的初始状态,而通常用均值和相关矩阵对它描述。为保证估计的无偏性,可选取如下值作为滤波初值。
                 x(0|z0) = E[x(0)] (注:x(|z0)表示用观测量x(0)对信号x(0)的最小均方误差估计)
                P(0) = E{[x(0) - E[x(0)]][x(0) - E[x(0)]]H}

卡尔曼滤波算法的递推步骤如下(公式就不输入了,具体可参考下面的例子):
步骤1:状态预测
步骤2:由观察信号z(n)计算新息过程
步骤3:一步预测误差自相关矩阵
步骤4:信息过程自相关矩阵
步骤5:卡尔曼增益
步骤6:状态估计
步骤7:状态估计误差自相关矩阵
步骤8:重复1-7,进行递推滤波计算。
卡尔曼滤波算法的递推流程框图


来一个信号u(n)由一个四阶AR模型例子(Matlab上菜)
clc; clear all; close all;
%% Necessary parameter
N = 4;                      % 状态向量维数
M = 1;                      % 观测向量维数
samples = 512;              % 样本量
trails = 100;               % 试验次数
den = [1, -1.6, 1.46, -0.616, 0.1525];   %AR parameter
num = 1;
noise = sqrt(0.0332) * randn(samples, trails);
signal = filter(num, den, noise);

%% Kalman Filter Algorithm
%initial
Q2 = 0.005;                 % 观察噪声自相关矩阵
signal_u = zeros(samples + 4, trails);     % 观测信号 u(n)
u = zeros(N, samples);                     %
c = zeros(samples, N);                     % 观察矩阵
K = zeros(N, samples);                     % 卡尔曼增益
A = zeros(num, samples);                   % 新息过程自相关矩阵
alpha = zeros(num, samples);               % 新息过程向量
omega = zeros(N, samples);                 % 预测器权向量
omega_aver = zeros(N, samples, trails);    %
P = zeros(N, N, samples);                  % 状态估计误差自相关矩阵
P(:, :, 1) = eye(N);                       %
F = eye(N);                                % 转移矩阵
J = zeros(samples, trails);                % 均方误差
for m = 1 : trails
    % 产生观测信号signal_u(:, m),注意这里加0主要是为了n=1时signal_u正确取数
    signal_u(:, m) = [0; 0; 0; 0; signal(:, m)];
%   signal_u(:, m) = [zeros(1, N - 1), signal(:, m)];
    for n = 2 : samples
        u(:, n) = signal_u(n + 3 : -1 : n, m).';
        c(n, :) = u(:, n)';
        alpha(n) = conj(signal(n, m)) - c(n, :) * omega(:, n - 1);
        A(n) = c(n, :) * P(:, :, n - 1) * c(n, :)' + Q2;
        K(:, n) = P(:, :, n - 1) * c(n, :)' /A(n);
        omega(:, n) = omega(:, n - 1) + K(:, n) * alpha(n);
        P(:, :, n) = (eye(4) - K(:, n) * c(n, :)) * P(:, :, n - 1);
        J(n, m) = sum(diag(P(:, :, n)));
    end
    omega_aver(:, :, m) = omega;
end
omega_ave = sum(omega_aver, 3)./trails;
J_ave = sum(J, 2)./trails;

%% Draw the picture of weight vector (1 times trial)
figure(1);
n = 1 : samples;
plot(n, omega(1, :),'LineWidth', 2);
hold on
plot(n, omega(2, :),':r','LineWidth', 2);
hold on
plot(n, omega(3, :),'--g','LineWidth', 2);
hold on
plot(n, omega(4, :), '-.k','LineWidth', 2);
title('Using Kalman Filter algorithm to estimate weighter vector (1 times trial)');
xlabel('iterative times n');
ylabel('weight vector');
legend('\omega1','\omega2','\omega3','\omega4',0);

%% Draw the picture of weight vector (100 times trial)
figure(2)
plot(n, omega_ave(1, :),'LineWidth', 2);
hold on
plot(n, omega_ave(2, :),':r','LineWidth', 2);
hold on
plot(n, omega_ave(3, :),'--g','LineWidth', 2);
hold on
plot(n, omega_ave(4, :), '-.k','LineWidth', 2);
title('Using Kalman Filter algorithm to estimate weighter vector (100 times trial)');
xlabel('iterative times n');
ylabel('weight vector');
legend('\omega1','\omega2','\omega3','\omega4',0);

%% Draw the picture of MSE(Mean Square Error) (100 times trial)
figure(3);                                       
plot(n, J_ave, 'LineWidth', 2);
xlabel('iterative times n');
ylabel('MSE');
title('基于Kalman算法的滤波器权系数的学习曲线');







使用特权

评论回复
43
nextpage| | 2015-5-22 09:29 | 只看该作者
你好,请问你做过nrf2401和TMS320c5509的无线语音通信么?最近在搞这个,发现播放时候有声音,但是已经听不懂是什么,这是什么原因啊?是不是两个AD之间nrf2401通信时间不够导致的啊?

使用特权

评论回复
44
nextpage| | 2015-5-22 09:34 | 只看该作者
Mark,谢谢楼主分享,期待更新

使用特权

评论回复
45
zhangmangui| | 2015-5-24 21:42 | 只看该作者
wopt 发表于 2015-4-9 21:18
3.8 kalman
推荐一篇关于kalman的**。

推荐的网址非常不错

使用特权

评论回复
46
ahczqmz| | 2015-5-25 17:19 | 只看该作者
楼主干脆出本书吧!
楼主做啥工作的?

使用特权

评论回复
47
wopt|  楼主 | 2015-5-26 18:35 | 只看该作者
本帖最后由 wopt 于 2015-5-26 18:42 编辑
nextpage 发表于 2015-5-22 09:29
你好,请问你做过nrf2401和TMS320c5509的无线语音通信么?最近在搞这个,发现播放时候有声音,但是已经听不 ...

我很少做这类的东西,所以以下给的建议仅供参考。

1、首先确定AD采样率,是不是欠采样。  如果本地播放没问题就看2
2、编码的时候误码率太高?  PCM编码?  如果编码没问题就看3
3、传输过可靠性   观察发送端波形与接收端波形对比,如果没有问题就看4
4、那只能是接收端了,发送端都搞定,接收端也应该差不了多少了。

Good luck!希望你能成功!

使用特权

评论回复
48
wopt|  楼主 | 2015-5-26 18:36 | 只看该作者
nextpage 发表于 2015-5-22 09:34
Mark,谢谢楼主分享,期待更新

好的,最近更新卡拉曼滤波。  

使用特权

评论回复
49
wopt|  楼主 | 2015-5-26 18:37 | 只看该作者
ahczqmz 发表于 2015-5-25 17:19
楼主干脆出本书吧!
楼主做啥工作的?

有这个打算。但不会5509的。  很可能是6748的,关于图像、视频方面的。:lol

使用特权

评论回复
50
wopt|  楼主 | 2015-5-26 18:38 | 只看该作者
zhangmangui 发表于 2015-5-24 21:42
推荐的网址非常不错

我回来了:lol  过几天继续写

使用特权

评论回复
51
ahczqmz| | 2015-5-26 21:53 | 只看该作者
楼主研究生吗?

使用特权

评论回复
52
Mrzhong| | 2015-6-2 11:29 | 只看该作者
楼主是做DSP图像处理研究的吗?

使用特权

评论回复
53
wopt|  楼主 | 2015-6-11 10:56 | 只看该作者
ahczqmz 发表于 2015-5-26 21:53
楼主研究生吗?

嗯,是的。

使用特权

评论回复
54
wopt|  楼主 | 2015-6-11 10:56 | 只看该作者
Mrzhong 发表于 2015-6-2 11:29
楼主是做DSP图像处理研究的吗?

菜鸟一枚

使用特权

评论回复
55
wopt|  楼主 | 2015-6-14 17:06 | 只看该作者
数字图像处理算法的编程
  • 明确的算法流程图
  • matlab等仿真软件中测试(设计简单的算法来验证输入,输出数据的正确性)
  • 算法移植(尽量采用c语言保证接口的通用型和可移植性,编写过程中不断调试,直到完成整个算法)


TMS320C550x Image Library

...\imglib
55ximage.lib 存储模式的图像处理库
55ximage.src 图像/视频处理函数的调用函数集合
55ximagex.lib 大存储模式的图像处理库



...\imglib\include
imagelib.h C语言函数声明头文件
imagesample.h 图像样本的头文件
wavelet.h 小波变换的头文件



Ti IMGLIB库简介.pdf (121.69 KB)


使用特权

评论回复
56
wopt|  楼主 | 2015-6-14 22:53 | 只看该作者
本帖最后由 wopt 于 2015-6-14 22:57 编辑

图像反色
  • 读入图片
  • 将图片每一个像素点取反

调试过程中关于image analyzer的使用参考
http://processors.wiki.ti.com/index.php/GSG:Debugging_projects#Displaying_images


后面关于图像的内容,尽量用matlab来实现

#include <stdio.h>

#define IMAG_EWIDTH   80
#define IMAG_EHEIGHT  80

void CreatImage(unsigned char *pImage,int nWidth,int nHeight);
void ReadImage(unsigned char *pImage,char *cFileName,int nWidth,int nHeight);
void Reverse(unsigned char *pImage, unsigned char *dbTargetImage, int nWidth,int nHeight);

unsigned char dbImage[IMAG_EWIDTH * IMAG_EHEIGHT];
unsigned char dbTargetImage[IMAG_EWIDTH * IMAG_EHEIGHT];
        
int main(void)
{
        CreatImage(dbImage,  IMAG_EWIDTH, IMAG_EHEIGHT);
        ReadImage(dbImage, "..\\1.bmp", IMAG_EWIDTH, IMAG_EHEIGHT);
        Reverse(dbImage, dbTargetImage, IMAG_EWIDTH, IMAG_EHEIGHT);
        
        while(1);
}               

void CreatImage(unsigned char *pImage,int nWidth,int nHeight)
{
        int x, y;
        int tmp1, tmp2;
        unsigned char *pWork = pImage;

        tmp1 = 256/ 16;
        tmp2 = nHeight / 16;

        for (y=0; y < nHeight;y ++ )
        {
                for (x = 0;x < nWidth; x++, tmp1++ )
                {
                        (*pWork) = (y / tmp2) * tmp1;
                }
        }
}


void ReadImage(unsigned char *pImage, char *cFileName, int nWidth, int nHeight)
{
        int j;
        unsigned char *pWork;
        FILE *fp;

        if (fp = fopen(cFileName, "rb"))
        {
                fseek(fp, 1078L, SEEK_SET);
                pWork = pImage + (nHeight - 1) * nWidth;
                for (j = 0; j < nHeight; j++, pWork -= nWidth)
                {
                        fread(pWork,nWidth,1,fp);
                }
                fclose(fp);
        }
}

void Reverse(unsigned char *pImage, unsigned char *dbTargetImage, int nWidth,int nHeight)
{
        int i, j;
        unsigned char *pImg = dbImage;
        unsigned char *pImg1 = dbTargetImage;
        for (i = 0; i < nHeight; i++ )
        {
                for (j = 0; j < nWidth; j++, pImg++, pImg1++)
                {
                        (*pImg1) = (~(*pImg)) & 0x0ff;
                }
        }
}




使用特权

评论回复
57
zhangmangui| | 2015-6-19 00:22 | 只看该作者
@21小跑堂   此贴我要打赏    为什么选择金额后   点击确定打赏   就没反应了
查看了   钱包里面是有钱的

使用特权

评论回复
58
wopt|  楼主 | 2015-7-3 21:11 | 只看该作者
本帖最后由 wopt 于 2015-7-4 16:17 编辑

4.2 数字图像的锐化

图像锐化的处理目的是使模糊的图像变得更加清晰起来。
图像模糊实质就是图像受到平均或积分运算造成的,因此可以对图像进行逆运算。如微分运算来使的图像清晰化。
从频谱角度来分析,图像模糊的实质是其高频分量被衰减,因而可以通过高通滤波来获得清晰图像。

能进行锐化处理的图像必须有较高的信噪比,否则锐化后图像信噪比反而更低,因此一般先减少噪声后再进行锐化。

图像锐化的两种方法:一、微分方法(如:拉普拉斯锐化);二、高通滤波法。
拉普拉斯运算是偏导数运算的线性组合,而且是一种各向同性(旋转不变)的线性运算。

关于拉普拉斯的算法细节自行查看相关资料”图像的拉普拉斯锐化“。最终简化为如下公式(非唯一):
g(i, j) = 5f(i, j) - f(i - 1, j) - f(i + 1, j) - f(i, j - 1)
为程序添加拉普拉斯锐化增强功能(假定对彩色图像进行处理),拉普拉斯锐化模板为3x3的矩阵:

0- 1 0
- 1 5 -1
0- 1 0


#define IMAGEWIDTH   80  // 图片宽度
#define IMAGEHEIGHT  80  // 图片长度

extern unsigned char dbImage[IMAGEWIDTH * IMAGEHEIGHT];     // 原图
extern unsigned char dbTargetImage[IMAGEWIDTH * IMAGEHEIGHT]; // 目标图

int mi, mj, m_nWork1, m_nWork2;    // 中间变量
unsigned int m_nWork, *pWork;     // 中间变量
unsigned char *pImg1, *pImg2, *pImg3, *pImg;  // 图像指针
unsigned int x11, x12, x13, x21, x22, x23, x31, x32, x33; // 矩阵 3x3

void laplace(int nWidth, int nHeight)
{
        int i;
        pImg = dbTargetImage;      // 目标图第一行元素清零
        for (i = 0; i < IMAGEWIDTH; i++, pImg++)
        {
                (*pImg) = 0;  
        }
        (*pImg) = 0;
        pImg1 = dbImage;   // 因为矩阵为3x3 所以先取图像的前三行
        pImg2 = pImg1 + IMAGEWIDTH;
        pImg3 = pImg2 + IMAGEWIDTH;
        for (i = 2; i < nHeight; i++)
        {
                pImg++;
                x11 = (*pImg1); pImag1++;
                x12 = (*pImg1); pImag1++;         
                x21 = (*pImg2); pImag2++;
                x22 = (*pImg2); pImag2++;
                x31 = (*pImg3); pImag3++;
                x32 = (*pImg3); pImag3++;

                for (mi = 2; mi < nWidth; mi++, pImg++, pImg1++, pImg2++, pImg3++)
                {
                        x13 = (*pImg1);
                        x23 = (*pImg2);
                        x33 = (*pImg3);
                        
                        m_nWork1 = x22 << 2;   // 等同于
                        m_nWork1 += x22;       // m_nWork1 =  x22 * 5
                        m_nWork2 = x12 + x21 + x23 + x32;

                        m_nWork1 -= m_nWork2;
                        if (m_nWork1 > 255)
                        {
                                m_nWork1 = 255;
                        }
                        else if (m_nWork1 < 0)
                        {
                                m_nWork1 = 0;
                        }
                        (*pImg) = m_nWork1;
                        x11 = x12;
                        x12 = x12;
                        x21 = x22;
                        x22 = x23;
                        x31 = x32;
                        x32 = x33;
                }
                (*pImg) = 0;
                pImg++;
        }
}








使用特权

评论回复
59
wopt|  楼主 | 2015-7-3 21:12 | 只看该作者
本帖最后由 wopt 于 2015-7-3 21:15 编辑

5.1 DSP/BIOS入门
基于CCS5.1建立BIOS工程.rar (3.48 MB)




使用特权

评论回复
60
wopt|  楼主 | 2015-7-3 21:17 | 只看该作者
本帖最后由 wopt 于 2015-7-4 17:36 编辑

G.711语音编码
G.711是一种工作在8KHz采样率模式下的脉冲编码调制(PCM)方案,采样值为8位。按照Nyquist定理的规定,fs≥2fH,所以G.711可以编码的频率范围为0-4KHz。G.711标准中定义的两个主要的算法:u-law和A-law。大学本科《通信原理》中就有介绍。我国使用A-law。

PCM编码的三个步骤:抽样、量化、编码。

ps..在电话网络中规定,传输语音部分采用0.3~3.3KHz的语音信号。而0~0.3KHz和3.3~4KHz未用,也被当成保护波段。
关于G.711和G.729一些文字:参考
http://jiaoyu.3158.cn/20130105/n5595270595830.html

unsigned char IntToALaw(int nInput)  //alaw转换,语音编码
{
        int segment;
        unsigned int i, sign,quant;
        unsigned int absol, temp;
        int nOutput;
        unsigned char cOutput;
        absol = abs(nInput);
        temp = absol;
        sign = (nInput >= 0)?1:0;
        for ( i=0;i<12;i++ )
        {
                nOutput = temp&0x4000;
                if ( nOutput )       
                {
                        break;
                }
                temp<<=1;
        }
        if ( i >= 12 )       
        {
                nOutput = 0;
        }
        else if( i>=7 && i<12 )
        {
                quant = (absol>>4)&0x0F;
                segment = 0;
                segment <<= 4;
                nOutput = segment+quant;
        }              
        else
        {
                segment = 7-i;        //segment代表4-6位的数值
                quant = (absol>>(segment+3))&0x0F;
                segment <<= 4;
                nOutput = segment+quant;
        }
        if(sign)
                nOutput ^= 0xD5;        //正数与之相异或得到编码后的字节
        else
                nOutput ^= 0x55;        //负数与之相异或得到编码后的字节
        cOutput=(unsigned char)nOutput;
        return cOutput;
}
int ALawToInt(unsigned char nInput)                //alaw反转换,语音解码
{
        int sign,segment;
        int temp,quant,nOutput;
        temp = nInput^0xD5;        //异或返回编码值
        sign = (temp&0x80)>>7;        //返回符号值
        segment = temp&0x70;
        segment >>= 4;
        if(segment == 0)
        {
                segment = 1;
            quant = temp&0x0F;        //得到abcd位
                quant <<= segment;
                quant = quant|0x01;
        }
        else
        {
                quant = temp&0x0F;
                quant += 0x10;
                quant <<= 1;
                quant = quant|0x01;
                quant <<= segment-1;//移位返回
        }
        //quant <<= 3;
        if ( sign )
                nOutput = -quant;
        else
                nOutput = quant;
        return nOutput;
}

unsigned int G711ALawEncode(int nLeft, int nRight)  //八位转十六位数据,nLeft是左声道数据,nRight是右声道数据
{
        unsigned char cL, cR;
        unsigned int uWork;
        cL = IntToALaw(nLeft);
        cR = IntToALaw(nRight);
        uWork = cL; uWork <<= 8; uWork |= cR;        //左声道高位,右声道低位
        return(uWork);
}


使用特权

评论回复
发新帖 本帖赏金 5.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则