演算法設計與分析實驗報告
① 計算機程序設計基礎的實驗報告怎麼寫
1
實驗要求
:
1.
實驗前按實驗報告格式要求,寫出預實驗報告,注意留出記錄結果的空間。
2.
認真實驗
,
注意記錄
3.
撰寫實驗報告
.
按時上交
.
實驗報告格式:
實驗
*
***** ***** *****
一、
實驗目的
照抄實驗指導的內容。
二、
實驗步驟和內容
包括:
1
.實驗題目要求。
2
.源程序清單
3
.預期結果
3
.上機執行或調試結果:包括原始數據、相應的運行結果和必要的說明
三、
實驗體會
調試中遇到的問題及解決辦法;若最終未完成調試,要試著分析原因;調試程
序的心得與體會;其他演算法的存在與實踐;對課程及實驗的建議等。
② 實驗報告怎麼寫啊
實驗名稱
要用最簡練的語言反映實驗的內容。如驗證某程序、定律、演算法,可寫成「驗證×××」;分析×××。
學生姓名、學號、及合作者
實驗日期和地點(年、月、日)
實驗目的
目的要明確,在理論上驗證定理、公式、演算法,並使實驗者獲得深刻和系統的理解,在實踐上,掌握使用實驗設備的技能技巧和程序的調試方法。一般需說明是驗證型實驗還是設計型實驗,是創新型實驗還是綜合型實驗。[2]
實驗設備(環境)及要求
在實驗中需要用到的實驗用物,葯品以及對環境的要求。
實驗原理
在此闡述實驗相關的主要原理。
實驗內容
這是實驗報告極其重要的內容。要抓住重點,可以從理論和實踐兩個方面考慮。這部分要寫明依據何種原理、定律演算法、或操作方法進行實驗。詳細理論計算過程。
實驗步驟
只寫主要操作步驟,不要照抄實習指導,要簡明扼要。還應該畫出實驗流程圖(實驗裝置的結構示意圖),再配以相應的文字說明,這樣既可以節省許多文字說明,又能使實驗報告簡明扼要,清楚明白。
具體的範文模板
鏈接:鏈接: https://pan..com/s/1cXhjjCVFxjqu_hYLWaTnRg
③ c語言程序設計題。實驗報告。高分。
車票系統,與你的第2題要求略有不同,你自己修改吧
#include<stdio.h>
#include<stdlib.h>
#include<dos.h>
#include<time.h>
#include<conio.h>
#include<string.h>
const int MAX=20;
const int N=50;
const int MAXFILENAME=100;
enum {FALSE,TRUE};
struct time
{
int hour;
int minutes;
};
struct ticket
{
int SerialNumber;
struct time SetOut;
char DeparturePoint[MAX];
char TerminalPoint[MAX];
float LastTime;
int FixNumber;
int FixedNumber;
}car[N];
int RecordNumber;
int FLAG=FALSE;
/**********************************************/
int ShowMessage(void); //載入原始數據
void mainmenu(void); //主菜單
void InsertMessage(void); //錄入班次信息
void SearchMenu(void); //查詢路線子菜單
void SearchByNumber(void); //按班次號查詢
void SearchByAddress(void); //按終點站查詢
void TicketManagement(void); //車票售出與退回
void TicketOrder(void); //售票
void TicketDelete(void); //退票
void exit(void); //退出該系統
/********************************************/
int main(void)
{
RecordNumber=ShowMessage();
if(1)
do{
mainmenu();
}while(FLAG==FALSE);
return 0;
}
void mainmenu(void)
{
system("color 1f");
system("mode con: cols=140 lines=130");
char functionNumber;
printf(" 車票管理系統\n\n");
printf(" 製作:hmm182007\n");
printf(" 日期:2007/11/25/19:57\n");
printf("============================================================================\n");
printf(" 1.錄入班次信息\t\n");
printf(" 2.瀏覽班次信息\t\n");
printf(" 3.查詢行車路線\t\n");
printf(" 4.售票與退票系統\t\n");
printf(" 5.退出該系統\t\n");
printf("============================================================================\n");
printf("請選擇你所需要的功能:");
scanf("%c",&functionNumber);
switch(functionNumber)
{
case '1':
{
InsertMessage();
printf("\n按任意鍵回主菜單......\n");
getchar();
getchar();
}
break;
case '2':
{
ShowMessage();
printf("\n按任意鍵回主菜單......\n");
getchar();
getchar();
}
break;
case '3':
{
SearchMenu();
printf("\n按任意鍵回主菜單......\n");
getchar();
getchar();
}
break;
case '4':
{
TicketManagement();
getchar();
getchar();
}
break;
case '5':FLAG=TRUE;exit();break;
default:
{
printf("輸入錯誤,請確保你的輸入為1--5.\n");
printf("按任意鍵回主菜單......\n");
getchar();
getchar();
}
}//switch ends
FLAG=FALSE;
}
void InsertMessage(void)
{
FILE *fp;
char filename[MAXFILENAME];
int i;
printf("請輸入文件名或者文件路徑名:");
scanf("%s",filename);
if((fp=fopen(filename,"r"))==NULL)
{
printf("文件%s不可讀,請確認文件%s存在或者文件路徑正確.\n\n",filename,filename);
mainmenu();
}
for(i=RecordNumber;!feof(fp)&&!ferror(fp);i++)
{
fscanf(fp,"%d%d%d",&car[i].SerialNumber,&car[i].SetOut.hour,&car[i].SetOut.minutes);
fscanf(fp,"%s%s%f%d%d",&car[i].DeparturePoint,&car[i].TerminalPoint,&car[i].LastTime,&car[i].FixNumber,&car[i].FixedNumber);
}
int count=i;
printf("班次\t發車時間\t起點\t終點\t行車時間(小時)\t額定載量\t已定票人數\n");
for(i=0;i<count;i++)
{
printf("%d\t%d:%d\t\t",car[i].SerialNumber,car[i].SetOut.hour,car[i].SetOut.minutes);
printf("%s\t%s\t\t%.1f\t %d\t\t%d\n",car[i].DeparturePoint,car[i].TerminalPoint,car[i].LastTime,car[i].FixNumber,car[i].FixedNumber);
}
fclose(fp);
}
int ShowMessage(void)
{
int i;
FILE *fp;
if((fp=fopen("add.txt","r"))==NULL)
{
printf("讀取數據失敗,請檢查文件add.txt是否存在.\n");
exit(-1);
}
for(i=0;!feof(fp)&&!ferror(fp);i++)
{
fscanf(fp,"%d%d%d",&car[i].SerialNumber,&car[i].SetOut.hour,&car[i].SetOut.minutes);
fscanf(fp,"%s%s%f%d%d",&car[i].DeparturePoint,&car[i].TerminalPoint,&car[i].LastTime,&car[i].FixNumber,&car[i].FixedNumber);
}
int count=i;
printf("班次\t發車時間\t起點\t終點\t行車時間(小時)\t額定載量\t已定票人數\n");
for(i=0;i<count;i++)
{
printf("%d\t%d:%d\t\t",car[i].SerialNumber,car[i].SetOut.hour,car[i].SetOut.minutes);
printf("%s\t%s\t\t%.1f\t %d\t\t%d\n",car[i].DeparturePoint,car[i].TerminalPoint,car[i].LastTime,car[i].FixNumber,car[i].FixedNumber);
}
return count;
}
void SearchMenu(void)
{
system("color 1f");
system("mode con: cols=140 lines=130");
char functionNumber;
printf(" 查詢子菜單\n");
printf("============================================================================\n");
printf(" 1.按班次號查詢\t\n");
printf(" 2.按終點站查詢\t\n");
printf(" 3.返回主菜單\t\n");
printf("============================================================================\n");
printf("請選擇你所需要的功能:");
scanf("%*c%c",&functionNumber);
switch(functionNumber)
{
case '1':SearchByNumber();break;
case '2':SearchByAddress();break;
case '3':
getchar();
mainmenu();
break;
default:
printf("輸入錯誤,請確保你的輸入為1--3.\n");
printf("按任意鍵回查詢子菜單......\n");
getchar();
getchar();
SearchMenu();
}
}
void SearchByNumber(void)
{
int SearchNumber;
printf("請輸入要查詢的班次號:");
scanf("%d",&SearchNumber);
printf("班次\t發車時間\t起點\t終點\t行車時間(小時)\t額定載量\t已定票人數\n");
printf("%d\t%d:%d\t\t",car[SearchNumber-1].SerialNumber,car[SearchNumber-1].SetOut.hour,car[SearchNumber-1].SetOut.minutes);
printf("%s\t%s\t\t%.1f\t %d\t\t%d\n",car[SearchNumber-1].DeparturePoint,car[SearchNumber-1].TerminalPoint,car[SearchNumber-1].LastTime,car[SearchNumber-1].FixNumber,car[SearchNumber-1].FixedNumber);
}
void SearchByAddress(void)
{
int i;
char Address[MAX];
printf("請輸入終點站的名稱:");
scanf("%s",&Address);
printf("班次\t發車時間\t起點\t終點\t行車時間(小時)\t額定載量\t已定票人數\n");
for(i=0;i<RecordNumber;i++)
{
//對比終點站記錄,找到並輸出
if((strcmp(Address,car[i].TerminalPoint))==0)
{
printf("%d\t%d:%d\t\t",car[i].SerialNumber,car[i].SetOut.hour,car[i].SetOut.minutes);
printf("%s\t%s\t\t%.1f\t %d\t\t%d\n",car[i].DeparturePoint,car[i].TerminalPoint,car[i].LastTime,car[i].FixNumber,car[i].FixedNumber);
}
}
}
void TicketManagement(void)
{
char functionNumber;
system("color 1f");
system("mode con: cols=140 lines=130");
printf(" 訂票與退票菜單\n");
printf("============================================================================\n");
printf(" 1.訂票\t\n");
printf(" 2.退票\t\n");
printf(" 3.返回主菜單.\n");
printf("============================================================================\n");
printf("選擇你需要的功能:");
scanf("%*c%c",&functionNumber);
switch(functionNumber)
{
case '1':
{
TicketOrder();
//getchar();
//getchar();
}
break;
case '2':TicketDelete();break;
case '3':
{
getchar();
mainmenu();
}
break;
default:
{
printf("輸入錯誤,請確保你的輸入為1--3.\n");
printf("按任意鍵回主菜單......\n");
getchar();
getchar();
mainmenu();
}
}
}
void TicketOrder(void)
{
int i;
printf("請輸入要訂購的車票的班次:");
scanf("%d",&i);
if(i<0||i>RecordNumber)
{
printf("對不起,今天沒有這趟車,請明天再來,謝謝使用!\n");
printf("按任意鍵回主菜單......\n");
getchar();//getchar();
TicketManagement();
}
time_t tval;
struct tm *now;
tval = time(NULL);
now = localtime(&tval);
if((now->tm_hour==car[i].SetOut.hour&&now->tm_min<car[i].SetOut.minutes)||(now->tm_hour<car[i].SetOut.hour))
{
if(car[i].FixedNumber<car[i].FixNumber)
{
car[i].FixedNumber++;
printf("你的訂票成功,請按時上車,謝謝使用!\n");
}
else printf("對不起,今天的這趟車的票已賣完,請明天再來,謝謝合作!\n");
}
else printf("對不起,今天的這趟車已發出,請明天再來,謝謝合作!\n");
printf("班次\t發車時間\t起點\t終點\t行車時間(小時)\t額定載量\t已定票人數\n");
printf("%d\t%d:%d\t\t",car[i-1].SerialNumber,car[i-1].SetOut.hour,car[i-1].SetOut.minutes);
printf("%s\t%s\t\t%.1f\t %d\t\t%d\n",car[i-1].DeparturePoint,car[i-1].TerminalPoint,car[i-1].LastTime,car[i-1].FixNumber,car[i-1].FixedNumber);
//printf("按任意鍵回主菜單......\n");
//getchar();getchar();
}
void TicketDelete(void)
{
int i;
printf("請輸入要退購的車票的班次:");
scanf("%d",&i);
if(i<0||i>RecordNumber)
{
printf("對不起,今天沒有這趟車,無法完成退票.謝謝使用!\n");
getchar();
//getchar();
TicketManagement();
getchar();
}
time_t tval;
struct tm *now;
tval = time(NULL);
now = localtime(&tval);
if((now->tm_hour==car[i].SetOut.hour&&now->tm_min<car[i].SetOut.minutes)||(now->tm_hour<car[i].SetOut.hour))
{
if(car[i].FixedNumber>=1)
{
car[i].FixedNumber--;
printf("退訂車票成功,謝謝使用!\n");
}
else printf("對不起,今天的這趟車的票尚未賣出,無法完成退票!\n");
}
else printf("對不起,今天的這趟車已發出,無法完成退票!\n");
printf("班次\t發車時間\t起點\t終點\t行車時間(小時)\t額定載量\t已定票人數\n");
printf("%d\t%d:%d\t\t",car[i-1].SerialNumber,car[i-1].SetOut.hour,car[i-1].SetOut.minutes);
printf("%s\t%s\t\t%.1f\t %d\t\t%d\n",car[i-1].DeparturePoint,car[i-1].TerminalPoint,car[i-1].LastTime,car[i-1].FixNumber,car[i-1].FixedNumber);
getchar();//getchar();
}
void exit(void)
{
printf("\n\n*********************謝謝使用本系統,歡迎下次繼續使用***********************\n");
exit(0);
}
④ 求一篇數值分析實驗報告
數值分析實驗報告
姓名: 學號:
實驗1:
1. 實驗項目的性質和任務
通過上機實驗,對病態問題、線性方程組求解和函數的數值逼近方法有一個初步理解。
2.教學內容和要求
1)對高階多多項式
編程求下面方程的解
並繪圖演示方程的解與擾動量 的關系。(實驗2.6)
2)對 ,生成對應的Hilbert矩陣,計算矩陣的條件數;通過先確定解獲得常向量b的方法,確定方程組
最後,用矩陣分解方法求解方程組,並分析計算結果。(第三章,實驗題4)
3)對函數
的Chebyshev點
編程進行Lagrange插值,並分析插值結果。(第四章 實驗1)
項目涉及核心知識點
病態方程求解、矩陣分解和方程組求解、Lagrange插值。
重點與難點
演算法設計和matlab編程。
1)a.實驗方案:
先創建一個20*50的零矩陣X,然後利用Matlab中的roots()和poly()函數將50個不同的ess擾動值所產生的50個解向量分別存入X矩陣中。然後再將ess向量分別和X的20個行向量繪圖。即可直觀的看出充分小的擾動值會產生非常大的偏差。即證明了這個問題的病態性。
b.編寫程序:
>> X=zeros(20,50);
>> ve=zeros(1,21);
>> ess=linspace(0,0.00001,50);k=1;
>> while k<=50
ve(2)=ess(k);
X(1:20,k)=roots(poly(1:20)+ve);
k=k+1;
end
>> m=1;
>> while m<=20
figure(m),plot(ess,X(m,:));
m=m+1;
end
C.實驗結果分析和拓展
由上面的實驗結果可以看出一個充分小的擾動值可以讓方程的解產生非常大的偏差,而且這個偏差隨著ess的變大偏差也隨即變大。但可以看出在相對小的根處根比較穩定,也就是說這些根關於ess並不敏感,而在較大根處時,根很不穩定,即這些解關於ess的變化是敏感的。這就說明了這個問題本身就是一個病態問題,與演算法好壞無關。
若擾動在x^18處,只要把程序中的ve(2)改為ve(3)即可,其圖形和此類似。
d.實驗結論:
高次多項式擾動求方程解問題是一個病態問題。
2)a.實驗方案:
先創建一個20*20的零矩陣A,再通過給定解x和Hilbert矩陣求出列向量b,然後通過LU分解法求出方程HX=b的解X,然後將x-X』這一行向量存入A矩陣中,形成一循環,最後,如果Hilbert矩陣非病態的話,則可輸出一個20*20的對角矩陣。
b.編寫程序:
>> n=2;
>> A=zeros(20,20);
>> while n<=20
x=1:n;
H=hilb(n);
b=H*x';
[L U]=lu(H);
y=L\b;X=U\y;
A(n,1:n)=x-X';
n=n+1;
end
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 4.455948e-017.
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 7.948463e-017.
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 1.798429e-016.
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 7.626119e-018.
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 6.040620e-017.
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 5.444860e-017.
>> A
A =
1.0e+003 *
Columns 1 through 10
0 0 0 0 0 0 0 0 0 0
-0.0000 0.0000 0 0 0 0 0 0 0 0
-0.0000 0.0000 -0.0000 0 0 0 0 0 0 0
-0.0000 0.0000 -0.0000 0.0000 0 0 0 0 0 0
0.0000 -0.0000 0.0000 -0.0000 0.0000 0 0 0 0 0
0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0 0 0 0
0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 0 0 0
-0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 0 0
-0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0
-0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000
-0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0000
-0.0000 0.0000 -0.0000 0.0000 -0.0000 0.0001 -0.0003 0.0006 -0.0007 0.0005
0.0000 -0.0000 0.0000 -0.0001 0.0005 -0.0027 0.0096 -0.0223 0.0348 -0.0361
0.0000 -0.0000 0.0000 -0.0004 0.0030 -0.0098 0.0080 0.0593 -0.2570 0.5154
0.0000 -0.0000 0.0000 -0.0001 0.0005 -0.0029 0.0095 -0.0171 0.0086 0.0347
0.0000 -0.0000 0.0000 -0.0000 0.0003 -0.0016 0.0059 -0.0133 0.0145 0.0094
0.0000 -0.0000 0.0000 -0.0001 0.0009 -0.0042 0.0118 -0.0182 0.0082 0.0185
0.0000 0.0000 -0.0000 0.0002 -0.0027 0.0187 -0.0762 0.1806 -0.2249 0.0813
0.0000 0.0000 -0.0000 0.0001 -0.0017 0.0120 -0.0497 0.1224 -0.1699 0.1064
0.0000 -0.0000 0.0000 -0.0003 0.0028 -0.0137 0.0371 -0.0464 -0.0164 0.1243
Columns 11 through 20
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
-0.0000 0 0 0 0 0 0 0 0 0
-0.0002 0.0000 0 0 0 0 0 0 0 0
0.0238 -0.0091 0.0015 0 0 0 0 0 0 0
-0.6091 0.4336 -0.1727 0.0296 0 0 0 0 0 0
-0.0944 0.1170 -0.0824 0.0318 -0.0053 0 0 0 0 0
-0.0624 0.1107 -0.1110 0.0674 -0.0232 0.0035 0 0 0 0
-0.0289 0.0059 0.0103 0.0082 -0.0263 0.0181 -0.0042 0 0 0
0.0524 0.1690 -0.3743 -0.1862 1.0944 -1.2171 0.6004 -0.1156 0 0
-0.0327 0.1652 -0.3051 -0.0485 0.7195 -0.9387 0.5714 -0.1699 0.0191 0
-0.1120 -0.0421 0.0883 0.0222 -0.0628 0.1013 -0.2902 0.3783 -0.2173 0.0469
C.實驗結果分析和拓展:
當Hilbert矩陣的階數比較小時,其解X和給定解x偏差不大;但當Hilbert矩陣的階數變大時,偏差就會變大。這就說明了Hilbert矩陣是一組病態矩陣,從Matlab運行中的Warning可以看出,其條件數相當大。
d.實驗結論:
Hilbert矩陣是一組病態矩陣,用它來做線性方程的系數矩陣時,往往會得出與精確解相差較大的解。
3)a.實驗方案:
在區間【-1,1】上取點,先按Chebyshev取點,即xk=cos((2k-1)pi/2/(n+1))取點,然後再進行拉格朗日插值,繪出圖和插值點。而後再進行均勻取點再拉格朗日插值。將兩種插值結果進行比較。
b.編程實現:
for a=1:10
b=a+1;
for c=1:b
X(c)=cos((2*c-1)*pi/2/(a+1));
Y(c)=1/(1+25*X(c)^2);
x=-1:0.05:1;
end
m=length(x);
for i=1:m
z=x(i);s=0;
for k=1:b
L=1;
for j=1:b
if j~=k
L=L*(z-X(j))/(X(k)-X(j));
end
end
s=s+L*Y(k);
end
y(i)=s;
end
figure(1)
plot(x,y,'r');
hold on;
figure(2)
plot(X,Y,'b*')
hold on
end
for a=2:2:10
b=a+1;
X=linspace(-1,1,b);
Y=1./(1+25*X.^2);
x=-1:0.05:1;
m=length(x);
for i=1:m
z=x(i);s=0;
for k=1:b
L=1;
for j=1:b
if j~=k
L=L*(z-X(j))/(X(k)-X(j));
end
end
s=s+L*Y(k);
end
y(i)=s;
end
figure(1)
plot(x,y,'r');
hold on;
figure(2)
plot(X,Y,'b*')
hold on
end
C.實驗結果分析及拓展:
均勻插值時,當n比較大時,就會出現多項式插值的Runge現象,即當插值節點的個數n增加時,Lagrange插值多項式對原來函數的近似並非越來越好。當進行非等距節點插值時,其近似效果明顯要比均勻插值是要好。原因是非均勻插值時,在遠離原點處的插值節點比較密集,所以其插值近似效果要比均勻插值時的效果要好。
d.實驗結論:
利用Chebyshev點進行非等距節點插值的對原函數的近似效果要比均勻節點插值的好。
⑤ 計算機演算法設計與分析的內容簡介
《計算機演算法設計與分析(第3版)》為普通高等教育「十一五」國家級規劃教材,是計算機專業核心課程「演算法設計與分析」教材。全書以演算法設計策略為知識單元,系統介紹計算機演算法的設計方法與分析技巧。主要內容包括:演算法概述、遞歸與分治策略、動態規劃、貪心演算法、回溯法、分支限界法、隨機化演算法、線性規劃與網路流、NP完全性理論與近似演算法等。書中既涉及經典與實用演算法及實例分析,又包括演算法熱點領域追蹤。
為突出教材的可讀性和可用性,章首增加了學習要點提示;章末配有難易適度的習題,分為演算法分析題和演算法實現題兩部分;配套出版了《演算法設計與實驗題解》;並免費提供電子課件和教學網站服務。
⑥ 圖像邊緣檢測演算法的研究與實現 的開題報告
摘 要 針對基於PC實現的圖像邊緣檢測普遍存在的執行速度慢、不能滿足實時應用需求等缺點,本文藉助於TI公司的TMS320DM642圖像處理晶元作為數字圖像處理硬體平台,DSP/BIOS為實時操作系統,利用CCS開發環境來構建應用程序;並通過攝像頭提取視頻序列,實現對邊緣檢測Sobel運算元改進[1]。
關鍵詞 DM642;Sobel運算元;程序優化;圖像邊緣檢測
1 引言
邊緣是圖像中重要的特徵之一,是計算機視覺、模式識別等研究領域的重要基礎。圖像的大部分主要信息都存在於圖像的邊緣中,主要表現為圖像局部特徵的不連續性,是圖像中灰度變化比較強烈的地方,也即通常所說的信號發生奇異變化的地方。經典的邊緣檢測演算法是利用邊緣處的一階導數取極值、二階導數在階梯狀邊緣處呈零交叉或在屋頂狀邊緣處取極值的微分演算法。圖像邊緣檢測一直是圖像處理中的熱點和難點。
近年來,隨著數學和人工智慧技術的發展,各種類型的邊緣檢測演算法不斷涌現,如神經網路、遺傳演算法、數學形態學等理論運用到圖像的邊緣檢測中。但由於邊緣檢測存在著檢測精度、邊緣定位精度和抗雜訊等方面的矛盾及對於不同的演算法邊緣檢測結果的精度卻沒有統一的衡量標准,所以至今都還不能取得令人滿意的效果。另外隨著網路和多媒體技術的發展,圖像庫逐漸變得非常龐大;而又由於實時圖像的目標和背景間的變化都不盡相同,如何實現實時圖像邊緣的精確定位和提取成為人們必須面對的問題。隨著DSP晶元處理技術的發展,尤其是在圖像處理方面的提高如TMS320C6000系列,為實現高效的、實時的邊緣檢測提供了可能性[5]。在經典的邊緣檢測演算法中,Sobel邊緣檢測演算法因其計算量小、實現簡單、處理速度快,並且所得的邊緣光滑、連續等優點而得到廣泛的應用。本文針對Sobel演算法的性能,並藉助於TMS320DM642處理晶元[3],對該邊緣檢測演算法進行了改進和對程序的優化,滿足實時性需求。
2 Sobel邊緣檢測演算法的改進
經典的Sobel圖像邊緣檢測演算法,是在圖像空間利用兩個方向模板與圖像進行鄰域卷積來完成的,這兩個方向模板一個是檢測垂直邊緣,一個是檢測水平邊緣。演算法的基本原理:由於圖像邊緣附近的亮度變化較大,所以可以把那些在鄰域內,灰度變化超過某個適當閾值TH的像素點當作邊緣點。Sobel演算法的優點是計算簡單,速度快。但由於只採用了兩個方向模板,只能檢測水平方向和垂直方向的邊緣,因此,這種演算法對於紋理較復雜的圖像,其邊緣檢測效果欠佳;同時,經典Sobel演算法認為,凡灰度新值大於或等於閾值的像素點都是邊緣點。這種判定依據是欠合理的,會造成邊緣點的誤判,因為多雜訊點的灰度新值也很大。
2.1 圖像加權中值濾波
由於圖像中的邊緣和雜訊在頻域中均表現為高頻成分,所以在邊緣檢測之前有必要先對圖像進行一次濾波處理,減少雜訊對邊緣檢測的影響。中值濾波是一種非線性信號的處理方法[2],在圖像處理中,常用來保護邊緣信息;保證濾波的效果。加權中值濾波,首先對每個窗口進行排序,取適當的比例,進行曲線擬合,擬合後的曲線斜率表徵了此窗口的圖像特徵,再根據圖像各部分特性適當的選擇權重進行加權。
2.2 增加方向模板
除了水平和垂直兩方向外,圖像的邊緣還有其它的方向,如135o和45o等,為了增加運算元在某一像素點檢測邊緣的精度,可將方向模板由2個增加為8個即再在經典的方向模板的基礎上增加6個方向模板,如圖1所示。
2.3 邊緣的定位及雜訊的去除
通常物體的邊緣是連續而光滑的,且邊緣具有方向和幅度兩個特徵,而雜訊是隨機的。沿任一邊緣點走向總能找到另一個邊緣點,且這兩個邊緣點之間的灰度差和方向差相近。而雜訊卻不同,在一般情況下,沿任一雜訊點很難找到與其灰度值和方差相似的雜訊點[4]。基於這一思想,可以將雜訊點和邊緣點區分開來。對於一幅數字圖像f(x,y),利用上述的8個方向模板Sobel運算元對圖像中的每個像素計算,取得其中的最大值作為該點的新值,而該最大值對應的模板所表示的方向為該像素點的方向。若|f(x,y)-f(x+i,y+j)|>TH2,對於任意i=0,1,-1;j=0,1,-1均成立,則可判斷點(x,y)為雜訊點。圖2給出了圖像邊緣檢測系統改進演算法的軟體流程圖。
圖1 邊緣檢測8個方向模板
圖2 系統結構圖
3 基於TMS320DM642的圖像處理的設計及演算法優化
3.1 TMS320DM642功能模塊及圖像處理系統的硬體結構
DSP以高速數字信號處理為目標進行晶元設計,採用改進的哈佛結構(程序匯流排和數據匯流排分開)、內部具有硬體乘法器、應用流水線技術、具有良好的並行性和專門用於數字信號處理的指令及超長指令字結構(VLIW)等特點;能完成運算量大的實時數字圖像處理工作。
TMS320DM642是TI公式最近推出的功能比較強大的TMS320C6x系列之一,是目前定點DSP領域里性能較高的一款[6]。其主頻是600MHz,8個並行運算單元、專用硬體邏輯、片內存儲器和片內外設電路等硬體,處理能力可達4800MIPS。DM642基於C64x內核,並在其基礎上增加了很多外圍設備和介面,因而在實際工程中的應用更為廣泛和簡便。本系統使用50 MHz晶體震盪器作為DSP的外部時鍾輸入,經過內部鎖相環12倍頻後產生600 MHz的工作頻率。DM642採用了2級緩存結構(L1和L2),大幅度提高了程序的運行性能。片內64位的EMIF(External Memory Interface)介面可以與SDRAM、Flash等存儲器件無縫連接,極大地方便了大量數據的搬移。更重要的是,作為一款專用視頻處理晶元,DM642包括了3個專用的視頻埠(VP0~VP2),用於接收和處理視頻,提高了整個系統的性能。此外,DM642自帶的EMAC口以及從EMIF 口擴展出來的ATA口,還為處理完成後產生的海量數據提供了存儲通道。
本系統是採用瑞泰公司開發的基於TI TMS320DM642 DSP晶元的評估開發板——ICETEK DM642 PCI。在ICETEK DM642 PCI評估板中將硬體平台分為五個部分,分別是視頻採集、數據存儲、圖像處理、結果顯示和電源管理。視頻採集部分採用模擬PAL制攝像頭,配合高精度視頻A/D轉換器得到數字圖像。基於DSP的視頻採集要求對視頻信號具備採集,實時顯示、對圖像的處理和分析能力。視頻A/D采樣電路—SAA7115與視頻埠0或1相連,實現視頻的實時採集功能。視頻D/A電路—SAA7105與視頻口2相連,視頻輸出信號支持RGB、HD合成視頻、PAL/NTSC復合視頻和S端子視頻信號。通過I2C匯流排對SAA7105的內部寄存器編程實現不同輸出。
整個系統過程由三個部分組成:圖像採集—邊緣處理—輸出顯示,如圖2所示。攝像頭採集的視頻信號經視頻編碼器SAA7115數字化,DM642通過I2C匯流排對SAA7115進行參數配置。在SAA7115內部進行一系列的處理和變換後形成的數字視頻數據流,輸入到核心處理單元DM642。經過DSP處理後的數字視頻再經過SAA7105視頻編碼器進行D/A轉換後在顯示器上顯示最終處理結果。
3.2 圖像處理的軟體設計和演算法優化的實現
由於在改進Sobel邊緣檢測運算元性能的同時,也相對增加了計算量,尤其是方向模板的增加,每個像素點均由原來的2次卷積運算增加為8次卷積運算,其實時性大大減弱。為了改進上述的不足,在深入研究處理系統和演算法後,針對TMS320DM642的硬體結構特點,研究適合在TMS320DM642中高效運行的Sobel改進演算法,滿足實時處理的要求。整個程序的編寫和調試按照C6000軟體開發流程進行,流程分為:產生C代碼、優化C代碼和編寫線性匯編程序3個階段。使用的工具是TI的集成開發環境CCS。在CCS下,可對軟體進行編輯、編譯、調試、代碼性能測試等工作。在使用C6000編譯器開發和優化C代碼時[7-8],對C代碼中低效率和需要反復調用的函數需用線性匯編重新編寫,再用匯編優化器優化。整個系統的控制以及數字圖像處理是用C程序實現,大部分軟體設計採用C程序實現,這無疑提高了程序的可讀性和可移植性,而匯編程序主要是實現DM642的各部分初始化。其邊緣檢測優化演算法在DM642中的實現步驟具體如下:
S1:根據DM642的硬體結構要求和控制寄存器設置,初始化系統並編寫實現邊緣檢測演算法的C程序。
S2:藉助CCS開發環境的優化工具如Profiler等產生.OUT文件。
S3:根據產生的附件文件如.MAP文件,分析優化結果及源程序結構,進一步改進源程序和優化方法。
S4:使用CCS中調試、鏈接、運行等工具,再生成.OUT可執行文件。
S5:運行程序,如果滿足要求則停止;否則重復步驟S2~S4直至滿足使用要求。
4 實驗結果
本文以Lena圖像為例根據上述的硬體環境和演算法實現的原理和方法,圖4~圖6分別給出了在該系統下採集的視頻Lena圖像及使用邊緣檢測運算元和改進後處理的結果。由實驗結果可以看出,在該系統下能實時完成視頻圖像的處理,並且給出的邊緣檢測運算元能較好的消除雜訊的影響,邊緣輪廓清晰。該演算法不僅能抑制圖像中大部分雜訊和虛假邊緣,還保證了較高的邊緣點位精度。
圖4 Lena原始圖像 圖5 傳統Sobel運算元 圖6 改進Sobel運算元
5 總結
本文實現了在TMS320DM642評估板上用改進的Sobel運算元對實時圖像進行邊緣檢測,無延遲地得到邊緣圖像。邊緣檢測效果較好,既提高了圖像檢測的精度又滿足了實時性的要求。從檢測結果看,利用該改進後的運算元在邊緣精確定位、邊緣提取都達到了很好的效果,且抗雜訊能力強,並為目標跟蹤、無接觸式檢測、自動駕駛、視頻監控等領域的應用提供了堅實的基礎。
參考文獻
[1] 王磊等. 基於Sobel理論的邊緣提取改善方法[J].中國圖像圖形學報,2005.10
[2] 陳宏席. 基於保持平滑濾波的Sobel運算元邊緣檢測.蘭州交通大學學報,2006,25(1):86—90
[3] 熊偉. 基於TMS320DM642的多路視頻採集處理板卡硬體設計與實現[ M]. 國外電子元器件,2006
[4] 朱立.一種具有抗雜訊干擾的圖像邊緣提取演算法的研究[J].電子技術應用.2004,25(1)
[5] 劉松濤,周曉東.基於TMS320C6201的實時圖像處理系統[J].計算機工程,2005(7):17—23
[6] TI TMS320DM642 video/imaging fixed-point digital signal processor data manual,2003
[7] TMS320C6x Optimizing C Compiler User』s Guide』 TEXAS INSTRUMENTS」,2002
[8] TMS320C32x Optimizing C/C++ Compiler User's Guide,Texas Instruments Incorporated,2001
⑦ C語言程序設計實驗報告怎麼寫啊
通過本試驗初步培養計算機邏輯解題能力。熟練掌握賦值語句和if語句的應用;掌握switch多路分支語句和if嵌套語句的使用
⑧ 一、實驗目的 1.掌握用 C語言調試程序的基本方法。 2.掌握線性表的基本運算,如插入、刪除等。 二、實驗
#include
<stdio.h>
#include
<stdlib.h>
#define
MAXSIZE 20
typedef
int ElemType;
typedef
struct
{
ElemType a[MAXSIZE];
int
length;
}SqList;
SqList
a,b,c;
void
creat_list(SqList *L);
void
out_list(SqList L);
void
insert_sq(SqList *L,int i,ElemType e);
int
locat_sq(SqList L,ElemType e);
void
DeleteList(SqList *L,int i)
;
main()
{
int i,k,loc; ElemType e,x;
do
{ printf("\n\n\n");
printf("\n
1. creat " );
printf("\n
2. insert");
printf("\n
3. delete");
printf("\n
4. find");
printf("\n
5. end");
printf("\n***************");
printf("\n
input:1-5");
scanf("%d",&k);
switch(k)
{
case 1:{ creat_list(&a); out_list(a);} break;
case
2:{ printf("\n i,e=?"); scanf("%d,%d",&i,&e);
insert_sq(&a,i,e);
out_list(a);
}
break;
case
3:{ printf("\n i=?"); scanf("%d",&i);
DeleteList(&a,i);
out_list(a);
}
break;
case
4:{ printf("\n e=?"); scanf("%d",&e);
loc=locat_sq(a,e);
if
(loc==-1) printf("\n not find
%d",loc);
else
printf("\n find wei shi
%d",loc);
}
break;
}
/* switch */
}while(k!=5);
printf("\n
byebye");
printf("\n
enter,return");
}
void
creat_list(SqList *L)
{
int i;
printf("\n
n=?"); scanf("%d",&L->length);
for(i=0;i<L->length;i++){
printf("\t data %d=?",i);
scanf("%d",&(L->a[i]));
}
}
/* creat_list */
void
out_list(SqList L)
{
int i; char ch;
printf("\n");
for(i=0;i<=L.length-1;i++)
printf("%10d",L.a[i]);
printf("\n\n
");
}
/* out_list */
void
insert_sq(SqList *L,int i,ElemType e)
{
int j;
if
(L->length==MAXSIZE) printf("\n overflow !");
else
if(i<1||i>L->length+1) printf("\n erroe i !");
else
{ for(j=L->length-1; j>i-1; j--) L->a[j+1]=L->a[j];
L->a[j+1]=e;
L->length++;}
}
/* insert_sq */
int
locat_sq(SqList L, ElemType e)
{
int i=0;
while(i<=L.length-1
&& L.a[i]!=e) i++;
if(i<=L.length-1)
return(i+1);
else
return(-1);
}/*
locat_sq */
void
DeleteList(SqList *L,int i)
{
}
⑨ c語言程序設計實驗報告
五、 課程設計小結心得體會
1設計思想
1)、設定一個一維數組,可先按員工序號設定每位員工的工資
2)、利用While語句和Prinft語句完成用戶菜單的設計
功能為:第1項 設為員工編號和工資數據
第2項 設為修改員工工資數據
第3項 設為查詢員工工資數據
第4項 設為結束系統
3)、當用戶選擇1、2項時,需輸入員工編號,所以需要設計編號校正功能,如果出錯可輸出「The error employe number」
4)、當選擇2時,進行工資數據的修改,並將新數據存回該員工的工資數組中
5)、利用for循環中判斷語句,將用戶工資數與數組中的工資數進行比較,如相同則輸出,將計數器加1,如此下去,直到把整個數組遍歷一遍
6)、判斷計數器是否為0, 是0表示找不到相符的工資,如果不為0,則輸出共查出幾比相符的工資
以上當然裡面也涉及了「函數的模塊化」理念,可以避免但需要重復列印頭文件時重復編寫列印信頭的語句。像這樣的程序是多見的,這樣不但降低了程序還發效率,而且耗時浪費資源「共用體」的使用簡化了程序的「復雜」性,正如(4)中,學號與姓名同時表示一個人,但在函數使用了「共用體」,從而程序的簡單可以便於糾錯,查找問題,避免了代碼的重復,這樣就給編譯時帶來了一定的難度與「量」的繁雜。一般不採取這樣的做法,力求「簡單、明了、清晰」。