程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj1009 Edge Detection 解題報告

poj1009 Edge Detection 解題報告

編輯:C++入門知識

主要解決三問題 1. 圖像的存儲 輸入采用的是RLE編碼,存儲也采用類似的方式,但要做點變換。比如輸入   7 15 4 100 15 25 2 175 2 25 5 175 2 25 5 0 0   經過變換,得到   7   15 4   100 19   25 21   175 23   25 28   175 30   25 35   其實就是把run length修改成了index分界值。這樣做的好處是:要知道第n個像素的值,直接跟其中index分界值進行比較即可,簡化了查找過程。   2. 每個像素edge值的計算 按照題目的要求,每個像素edge值是該像素與8鄰域的最大差值。可以采用這樣的處理方法:為8領域設置標志位,初始化均為true,表示鄰域存在,然後根據像素的index判斷它是否在圖像的邊界上,比如左上角的像素,其左邊和上邊的領域都不存在,根據不同的情況,對鄰域的標志位進行更新。最後,只考慮標志位為true的領域,取它的值與當前像素值求差值,進而確定edge值。   3. 提速的技巧 逐像素進行處理一定會超時的,這裡至少有兩個提速的技巧。一是多行像素相同的情況,這時將有一連串值為0的edge;二是多列像素布局相同的情況,這時將有一連串相同edge值。下面是上述兩種情況的例子   2   5 5000000   250 5000000   0 0   5000000   5 5000000   250 5000000   0 0   0   解題代碼 #include <stdio.h>   #include <stdlib.h>   // struct BLOCK   struct BLOCK   {       short value;       int   position;   };   const int N = 1005;   // CRLEImage   // class for run length encoded image   class CRLEImage   {   private:       BLOCK m_data[N];       int   m_count;       int   m_width;      public:       // constructor       CRLEImage() : m_count(0), m_width(0)       {           m_data[0].position = 0;           m_data[0].value    = -1;       }       // Scan       bool Scan()       {           int width, value, run_length;           scanf("%d", &width);           if( width == 0 ) {               printf("0\n");               return false;           }           m_width = width;           int i = 1, index = 0;           while(true)           {               scanf("%d %d", &value, &run_length);               if( value == 0 && run_length == 0)                   break;               index += run_length;               set_block(i, (short)value, index);               ++i;           }           m_count = i-1;           return true;       }       // Process       void Process()       {           printf("%d\n", m_width);           short last_edge = calculate_edge(1, 1), edge;           int last_idx = 1, idx = 2;           for(int i = 1; i <= m_count; ++i)           {               while(idx <= m_data[i].position)               {                   edge = calculate_edge(idx, i);                   // if edge value change                   if(edge != last_edge)                   {                       printf("%d %d\n", (int)last_edge, (idx - last_idx));                       last_idx = idx;                       last_edge = edge;                   }                   // same pixels in consecutive rows                   if(last_edge == 0 && idx - m_data[i-1].position > m_width + 1                                     && m_data[i].position - idx > m_width)                       idx = m_data[i].position - m_width;                   else ++idx;                   // same pixels in consecutive columns                   if(idx%m_width > 2 )                   {                       int same_length = m_width-1;                       int idx_arr[3] = { idx-m_width-2, idx-2, idx+m_width-2 };                       for( int j = 0; j < 3; ++j )                       {                           int location, temp;                           search_pixel(idx_arr[j], i, (idx_arr[j]<idx), location);                           if(location > 0)                           {                               temp  = m_data[location].position - idx_arr[j];                               if(temp < same_length)                                   same_length = temp;                           }                       }                       if(same_length > 2)                           idx += (same_length-2);                   }               }           }           printf("%d %d\n", (int)edge, (idx - last_idx));           printf("0 0\n");       }      private:       // set block       void set_block(int index, short value, int position)       {           m_data[index].value = value;           m_data[index].position = position;       }       // search pixel       short search_pixel(int idx, int block, bool bBackward, int& location)       {           if(idx < 1 || idx > m_data[m_count].position)           {               location = -1;               return 0;           }           int i = block;           if(bBackward)           {               for(i = block-1; i >= 0; --i)                   if(idx > m_data[i].position)                   {                       location = i+1;                                    return m_data[i+1].value;                   }           }           else           {               for(i = block; i <= m_count; ++i)                   if(idx <= m_data[i].position)                   {                       location = i;                       return m_data[i].value;                   }           }       }       // calculate edge       short calculate_edge(int idx, int block)       {           bool flag[8]; // does neighbor exist           for(int i = 0; i < 8; ++i)               flag[i] = true;           // top           if((idx - 1)/m_width == 0)                flag[0] = flag[1] = flag[2] = false;           // bottom           if(idx + m_width > m_data[m_count].position)                flag[5] = flag[6] = flag[7] = false;           // left (especially when width is 1)           if(m_width == 1 || idx % m_width  == 1 )               flag[0] = flag[3] = flag[5] = false;           // right           if(idx % m_width == 0 )               flag[2] = flag[4] = flag[7] = false;           // valid neighbor           short base = m_data[block].value;           short edge = 0;           int nidx; // index of neighbor short           for(int i = 0; i < 8; ++i)               if(flag[i])               {                   switch(i)                   {                   case 0:                   case 1:                   case 2:                       nidx = idx - m_width + i - 1;                       break;                   case 3:                       nidx = idx - 1;                       break;                   case 4:                       nidx = idx + 1;                       break;                   default:                       nidx = idx + m_width + i - 6;                   }                   short neighbor;                   int location;                   neighbor = search_pixel(nidx, block, (nidx<idx), location);                   short temp = ((neighbor > base) ? (neighbor - base) : (base - neighbor));                   if(temp > edge)                       edge = temp;               }           return edge;       }   };   // entry point   int main()   {       CRLEImage image;       while( image.Scan() )           image.Process();       return 0;   }    

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved