2015-04-02 97 views
0
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Drawing.Drawing2D; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

using Emgu.CV; 
using Emgu.CV.Util; 
using Emgu.CV.Structure; 

namespace DCTTransform 
{ 
    public partial class Form1 : Form 
    { 
     Image<Bgr, Byte> img; 
     Image<Ycc, Byte> imgYcc; 
     Bitmap bmp; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void btBrowse_Click(object sender, EventArgs e) 
     { 
      OpenFileDialog od = new OpenFileDialog(); 
      if (od.ShowDialog() == DialogResult.OK) 
      { 
       img = new Image<Bgr, byte>(od.FileName); 
       pcCitra.Image = img.ToBitmap(); 

       label1.Text = img.Width.ToString(); 
      } 
     } 

     //Split citra 
     public List<Image> subBlok(Image img, int blokX, int blokY) 
     { 
      List<Image> res = new List<Image>(); 
      int pembagiLebar = img.Width/blokX; 
      int pembagiTinggi = img.Height/blokY; 


      for (int i = 0; i < blokX; i++)//baris 
      { 
       for (int j = 0; j < blokY; j++)//kolom 
       { 
        Bitmap bmp = new Bitmap(img.Width/pembagiLebar, img.Height/pembagiTinggi); 
        //Bitmap bmp = new Bitmap(img.Width, img.Height); 

        Graphics grp = Graphics.FromImage(bmp); 
        grp.DrawImage(img, new Rectangle(0,0 , bmp.Width, bmp.Height), new Rectangle(j * bmp.Width, i * bmp.Height, bmp.Width, bmp.Height), GraphicsUnit.Pixel); 
        res.Add(bmp); 
       } 
      } 


      return res; 

     } 


     private void btTransform_Click(object sender, EventArgs e) 
     { 
      //SplitImage 
      List<Image> imgs = subBlok(pcCitra.Image, 8, 8); 

      pbDCT.Image = imgs[0]; 


     } 
    } 
} 

我已經做了這個代碼將圖像分成8 x 8像素,但結果顯示在左上角只有1塊(8 x 8)。如何將分割圖像顯示爲8x8像素?

所有我想要的是這樣的: |xxxx|xxxx|xxxx|xxxx|..........直到原始圖像的寬度相同。

你能幫我嗎?

回答

0

如果你想分割你的源圖像到多個8x8瓷磚,那麼你的轉換函數的循環是不正確的。如果你想將你的源圖像分成64個圖塊,那麼它們是正確的,但是DCT通常不能用於靜態圖像集。我是你想要哪一個目前還不清楚,但我固定它爲多個8x8的圖片在這裏:

 List<Image> res = new List<Image>(); 
     int pembagiLebar = (int)Math.Ceil((float)img.Width/(float)blokX); 
     int pembagiTinggi = (int)Math.Ceil((float)img.Height/(float)blokY); 


     for (int i = 0; i < pembagiLebar ; i++)//baris 
     { 
      for (int j = 0; j < pembagiTinggi ; j++)//kolom 
      { 
       Bitmap bmp = new Bitmap(blokX, blokY); 

       using (Graphics grp = Graphics.FromImage(bmp)) { 
        grp.DrawImage(img, 0, 0, new Rectangle(i * blokX, j * blokY, blokX, blokY), GraphicsUnit.Pixel); 
       } 

       res.Add(bmp); 
      } 
     } 


     return res; 

在右側和底部邊緣的邊界條件也討厭照顧(我還沒有在這裏) ,因爲源圖像尺寸可能不是8的倍數。

+0

謝謝它的作品:) – 2015-04-06 01:36:49

0

有幾種方法可以做。處理最簡單的方法是將圖像值存儲爲長度爲8的倍數的行。將數據填充。對於行數做同樣的操作。

然後塊(假設灰度)

X = starting point 

    v0 = X 
    v1 = X + 1 
    v2 = X + 2 
    . . . 
    v8 = X + row length 
    v9 = X + row length + 1 
    v10 = X + row length + 2 
    . . . 
    v63 = x = 7 * row length + 7 

    To move to the next block in the row X = X + 8. When you reach the end of the row 
    X = X + 8 * row length 

請記住,你的輸出要素必須輸入的兩倍。如果你的圖像數據是8位,你的DCT輸出將需要16位整數表示(或浮點值)。

如果你不能填充數據,最好的辦法就是將值複製到一個64位的數組中。你會做一個類似於上面的循環,但是,任何時候你需要訪問一個超出圖像寬度或高度的值時,在臨時數組中插入一個0。