Java課程設(shè)計(jì)-連通問題_第1頁
Java課程設(shè)計(jì)-連通問題_第2頁
Java課程設(shè)計(jì)-連通問題_第3頁
Java課程設(shè)計(jì)-連通問題_第4頁
Java課程設(shè)計(jì)-連通問題_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第1章課題概述本次數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)的題目是設(shè)計(jì)并實(shí)現(xiàn)位深度為1的bmp圖片的聯(lián)通問題。1.1課題的目的位深度為1的bmp圖片是只有黑白兩種顏色的圖片,信息比較容易讀取。連通:兩個(gè)點(diǎn)距離如果小于2個(gè)像素,則認(rèn)為這兩個(gè)點(diǎn)連通。也就是說以一個(gè)點(diǎn)為中心的九宮格中,圍繞它的8個(gè)點(diǎn)與它都是連通的。這個(gè)課題的目的是分析給出的黑白bmp圖片中所有獨(dú)立連通的群體,輸出每個(gè)連通群體的面積。所謂面積,就是它含有的像素的個(gè)數(shù)。1.2課題的要求1.2.1輸入輸出的要求(1)程序運(yùn)行后應(yīng)首先彈出一個(gè)窗口,窗口提供一個(gè)輸入圖片名稱的輸入框和確定按鈕。(2)輸入名稱,點(diǎn)擊確定后,彈出新的窗口,并在窗口中輸出各個(gè)連通區(qū)域的面積,每一行輸出一個(gè)。1.2.2程序?qū)崿F(xiàn)的功能要求(1)bmp圖片的信息儲存在圖片中,需要用流來讀取圖片的信息,并加以處理,使程序可以適用于任何像素的bmp圖片。(2)輸入格式有錯(cuò)誤要給出合適的提示。第2章概要設(shè)計(jì)2.1整個(gè)程序的模塊根據(jù)課題要求,整個(gè)程序可大致分為三個(gè)模塊,讀取圖片信息,處理圖片信息,計(jì)算連通。此外,還具有窗口,及簡短的說明提示等。程序各功能模塊的劃分,及主要流程如圖2-1所示。圖2-1整個(gè)程序模塊2.2bmp圖片信息分析偏移:10字節(jié),長度4字節(jié):圖像數(shù)據(jù)真正開始的位置。偏移:18字節(jié),長度4字節(jié):位圖的寬度,單位是像素。偏移:22字節(jié),長度4字節(jié):位圖的高度,單位是像素。Windows規(guī)定圖像文件中一個(gè)掃描行所占的字節(jié)數(shù)必須是4字節(jié)的倍數(shù),不足的位均以0填充。因此在編寫程序時(shí)要注意兩點(diǎn):(1)從圖片中讀取的數(shù)據(jù)為4個(gè)字節(jié),且將其倒置后,才是圖片的真正數(shù)據(jù)。(2)讀取的圖片像素的寬若不是4字節(jié)的倍數(shù),補(bǔ)0后會產(chǎn)生多余的數(shù)據(jù),需要經(jīng)過處理來跳過它們。2.3連通的判斷bmp圖片中像素黑色為0,白色為1。遍歷數(shù)組,遇到某連通區(qū)域的第一個(gè)黑色的點(diǎn)時(shí),改變其值為2,接著判斷后面的像素周圍是否存在黑色的像素,若存在,改變其值為除0,1之外最小的數(shù),否則,將該像素的值改為3,依次遞增1。當(dāng)周圍有兩種或以上不同連通區(qū)域的像素時(shí),例如2,3。將其值改為2后,要將二維數(shù)組中所有的3改為2。當(dāng)遍歷一次后,數(shù)出二維數(shù)組中除了0,1之外相同數(shù)字的個(gè)數(shù),即連通區(qū)域的面積。例如題目中的t1.bmp:這張圖的連通區(qū)域有9個(gè),8個(gè)面積為1和一個(gè)面積為11。下面三張圖片說明了改變像素值,并輸出不同數(shù)字個(gè)數(shù)的過程。為了方便觀察,用A來代替10,B來代替11,依次類推。圖2.3.1改變某連通區(qū)域第一個(gè)像素值圖2.3.2像素周圍有大于1的數(shù)的情況后面的像素與前面幾個(gè)像素修改方法相同。圖2.3.3修改完成后的像素圖第3章程序功能的實(shí)現(xiàn)3.1讀取圖片信息用DataInputStream來讀取圖片中的信息,讀取4個(gè)字節(jié)后,用handleByte()方法來處理數(shù)組,得到圖片的信息。用多重for循環(huán)將讀取到的像素信息處理并存入二維數(shù)組中。代碼如下:privateinthandleByte(byte[]b){ StringBuffersb=newStringBuffer(); for(inti=b.length-1;i>=0;i--){ StringBuffertemp=newStringBuffer(Integer.toBinaryString(b[i])); Stringfin="00000000"; if(b[i]!=0){ if(temp.length()>8){ fin=temp.substring(temp.length()-8); } while(temp.length()<8){ temp.insert(0,0); fin=temp.toString(); } } sb.append(fin); } returnInteger.parseInt(sb.toString(),2);} privatevoidloadPicture(Filedirectory,StringfileName){ DataInputStreamdis=null; al=newArrayList<Integer>(); try{ dis=newDataInputStream(newFileInputStream(directory.getAbsolutePath()+"/"+fileName+".bmp")); byte[]l=newbyte[4]; dis.skip(10); dis.read(l); intlocation=handleByte(l); byte[]len=newbyte[4]; dis.skip(4); dis.read(len); pWidth=handleByte(len);byte[]wid=newbyte[4]; dis.read(wid); pHeight=handleByte(wid); dis.skip(location-26); arr=newint[pHeight][pWidth]; for(introw=arr.length-1;row>=0;row--){ intcol=0; for(intn=0;n<Math.ceil((double)arr[row].length/8);n++){ StringBufferi=newStringBuffer(Integer.toBinaryString(dis.readByte())); while(i.length()<8){ i.insert(0,0); } Strings=i.substring(i.length()-8); for(intj=0;j<s.length()&&col<arr[row].length;j++,col++){ arr[row][col]=Character.digit(s.charAt(j),10); if(col==arr[row].length-1){ doubleskiper=Math.ceil((double)pWidth/32.0)*4-Math.ceil((double)pWidth/8.0); dis.skip((long)skiper); } } } } }catch(FileNotFoundExceptione){ JOptionPane.showMessageDialog(null,"找不到文件!請確認(rèn)圖片名稱且圖片位于“cPicture”文件夾中!","Error!",JOptionPane.ERROR_MESSAGE);tf.setText(""); tf.grabFocus(); flag=false; }catch(IOExceptione){ e.printStackTrace(); }finally{ try{ if(dis!=null){ dis.close(); } }catch(IOExceptione){ e.printStackTrace(); } }3.2判斷連通定義一個(gè)變量來存儲替換的值,用一個(gè)容器來存儲一個(gè)像素周圍的大于1的像素值,方便比較。先處理只有一行和只有一列的特殊情況,之后再處理其他的情況。其他情況中又分成了四個(gè)角,四條邊,其他像素,共9種情況。privatevoidchangeValue(){ value=2; ArrayList<Integer>temp=newArrayList<Integer>(); if(pHeight==1){ for(inti=0;i<arr.length;i++){ for(intj=0;j<arr[i].length;j++){ if(arr[i][j]==0){ if(j==0){ arr[i][j]=value; value++; continue; } if(arr[i][j-1]>1){ arr[i][j]=arr[i][j-1]; }else{ arr[i][j]=value; value++; } } } } }elseif(pWidth==1){ for(inti=0;i<arr.length;i++){ for(intj=0;j<arr[i].length;j++){ if(arr[i][j]==0){ if(i==0){ arr[i][j]=value; value++; continue; } if(arr[i-1][j]>1){ arr[i][j]=arr[i-1][j]; }else{ arr[i][j]=value; value++; } } } } }else{ for(inti=0;i<arr.length;i++){ for(intj=0;j<arr[i].length;j++){ if(arr[i][j]==0){ if(i==0&&j==0){ if(arr[i][j+1]<2&&arr[i+1][j+1]<2&&arr[i+1][j]<2){ arr[i][j]=value; value++; continue; } } if(i==0&&j>0&&j<arr[i].length-1){ if(arr[i][j+1]<2&&arr[i+1][j+1]<2&&arr[i+1][j]<2&&arr[i+1][j-1]<2&&arr[i][j-1]<2){ arr[i][j]=value; value++; continue; } } if(i==0&&j==arr[i].length-1){ if(arr[i+1][j]<2&&arr[i+1][j-1]<2&&arr[i][j-1]<2){ arr[i][j]=value; value++; continue; } } if(j==arr[i].length-1&&i>0&&i<arr.length-1){ if(arr[i-1][j]<2&&arr[i+1][j]<2&&arr[i+1][j-1]<2&&arr[i][j-1]<2&&arr[i-1][j-1]<2){ arr[i][j]=value; value++; continue; } } if(j==arr[i].length-1&&i==arr.length-1){ if(arr[i-1][j]<2&&arr[i][j-1]<2&&arr[i-1][j-1]<2){ arr[i][j]=value; value++; continue; } } if(i==arr.length-1&&j>0&&j<arr[i].length-1){ if(arr[i-1][j]<2&&arr[i-1][j+1]<2&&arr[i][j+1]<2&&arr[i][j-1]<2&&arr[i-1][j-1]<2){ arr[i][j]=value; value++; continue; } } if(i==arr.length-1&&j==0){ if(arr[i-1][j]<2&&arr[i-1][j+1]<2&&arr[i][j+1]<2){ arr[i][j]=value; value++; continue; } } if(j==0&&i>0&&i<arr.length-1){ if(arr[i-1][j]<2&&arr[i-1][j+1]<2&&arr[i][j+1]<2&&arr[i+1][j+1]<2&&arr[i+1][j]<2){ arr[i][j]=value; value++; continue; } } if(i>0&&i<arr.length-1&&j>0&&j<arr[i].length-1){ if(arr[i-1][j]<2&&arr[i-1][j+1]<2&&arr[i][j+1]<2&&arr[i+1][j+1]<2&&arr[i+1][j]<2&&arr[i+1][j-1]<2&&arr[i][j-1]<2&&arr[i-1][j-1]<2){ arr[i][j]=value; value++; continue; } } if(i-1>=0&&arr[i-1][j]>1){ temp.add(arr[i-1][j]); } if((i-1>=0&&j+1<pWidth)&&arr[i-1][j+1]>1){ temp.add(arr[i-1][j+1]); } if(j+1<pWidth&&arr[i][j+1]>1){ temp.add(arr[i][j+1]); } if((i+1<pHeight&&j+1<pWidth)&&arr[i+1][j+1]>1){ temp.add(arr[i+1][j+1]); } if(i+1<pHeight&&arr[i+1][j]>1){ temp.add(arr[i+1][j]); } if((i+1<pHeight&&j-1>=0)&&arr[i+1][j-1]>1){ temp.add(arr[i+1][j-1]); } if(j-1>=0&&arr[i][j-1]>1){ temp.add(arr[i][j-1]); } if((i-1>=0&&j-1>=0)&&arr[i-1][j-1]>1){ temp.add(arr[i-1][j-1]); } if(temp.size()!=0){ Collections.sort(temp); if(temp.get(0)==temp.get(temp.size()-1)){ arr[i][j]=temp.get(0); }else{ arr[i][j]=temp.get(0); for(intindex=1;index<temp.size();index++){ if(temp.get(index)>temp.get(0)){ for(ints=0;s<arr.length;s++){ for(intd=0;d<arr[s].length;d++){ if(arr[s][d]==temp.get(index)){ arr[s][d]=temp.get(0); } } } } } } } } temp.clear(); } } }第4章調(diào)試及發(fā)現(xiàn)問題的解決在編寫程序的過程中,我遇到了許多問題,但通過認(rèn)真的思考,最終都全部解決了。程序?qū)崿F(xiàn)及調(diào)試過程中遇到的主要問題及解決方法如下:1、讀取的字節(jié)的數(shù)值如果大于127,則會被當(dāng)成負(fù)數(shù),如何讓它恢復(fù)原來的數(shù)值?解決方法:在讀取一個(gè)字節(jié)后,將其轉(zhuǎn)換為整型二進(jìn)制字符串,若長度大于8,截取后8位,若長度小于8,在前面補(bǔ)0。最后將四個(gè)字節(jié)的字符串連接在一起,再轉(zhuǎn)換為int類型的數(shù)。2、若圖片像素的寬不是32的倍數(shù),則輸出結(jié)果會出錯(cuò)。解決方法:Windows規(guī)定圖像文件中一個(gè)掃描行所占的字節(jié)數(shù)必須是4字節(jié)的倍數(shù),這32個(gè)像素中,一旦達(dá)到圖片像素的最大寬度,后面的位的值為補(bǔ)的0,不代表任何一個(gè)像素,因此只要通過計(jì)算跳過這些沒有用的像素,即可解決。代碼如下:doubleskiper=Math.ceil((double)pWidth/32.0)*4–Math.ceil((double)pWidth/8.0);dis.skip((long)skiper);3、連通問題如何比較周圍像素的值?解決方法:將8個(gè)像素中大于1的值存入一個(gè)容器,方便比較。4、若輸入的名稱錯(cuò)誤或名稱為空時(shí),依然會彈出輸出結(jié)果的窗口,如何讓它不彈出?解決方法:定義一個(gè)boolean的值flag,默認(rèn)為false。setVisible(flag)的參數(shù)為這個(gè)boolean值。當(dāng)二維數(shù)組不為空時(shí),說明名稱和圖片格式?jīng)]有錯(cuò)誤,把這個(gè)值改為true。若名稱為空或不正確,flag的值不變,窗口不再顯示。第5章程序測試及分析運(yùn)行程序,彈出一個(gè)窗口,可以輸入圖片名

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論