2015-07-10 32 views
0

我想使用OpenCV將分辨率2048x2048的圖像分割成像素周圍分辨率爲90x90的一些*像素的較小圖像。後來在那些較小的圖像上我想使用foveation。我遵循這個例子在foveation一個圖像,而是python我正在使用C++。
OpenCV距離轉換不工作,因爲它應該

Image foveation in Python

 Mat mask = Mat::ones(Size(90,90), CV_8UC1) * 255; 
     circle(mask, CvPoint(45,45), 30, 0, -1); 

     Mat out; // = Mat::ones(Size(90,90), CV_32FC1) * 0; 
     distanceTransform(mask, out, CV_DIST_L2, CV_DIST_MASK_PRECISE); 


     int scale_factor = 10; 
     Mat filtered = outputImage.clone(); 
     Mat img_float; 
     filtered.convertTo(img_float,CV_32F,1,0); 

     for(int k = 0; k < 90; k++){ // y 
      for(int l = 0; l < 90; l++){ // x 
       if(out.at<float>(k,l) == 0.0) continue; 

       float mask_val = ceil(out.at<float>(k,l)/scale_factor); 
       if(mask_val <= 3) mask_val = 3; 

       int beginx = l - int(mask_val/2); 
       if (beginx < 0) 
        beginx = 0; 

       int beginy = k - int(mask_val/2); 
       if (beginy < 0) 
        beginy = 0; 

       int endx = l+int(mask_val/2); 
       if (endx >= 90) 
        endx = 90-1; 

       int endy = k+int(mask_val/2); 
       if (endy >= 90) 
        endy = 90-1; 

       int num = 0; 
       float total = 0; 
       for (int a = beginx; a < endx; a++){ 
        for(int b = beginy; b < endy; b++){ 
         num ++; 
         total += img_float.at<float>(a,b); 
        } 
       } 

       filtered.at<float>(k,l) = (total/num); 
      } 
     } 

     namedWindow("Display window", WINDOW_AUTOSIZE); 
     imshow("Display window", filtered); 
     waitKey(0); 
     imwrite(ss.str(), filtered, compression_params); 

在另一個問題在這裏,我讀了,而不是使用3或5中distanceTransform參數我應該使用CV_DIST_MASK_PRECISE。

問題是,我的墊子有時是黑色的,有時是白色的圓形,但它不能被保存或在代碼中使用。

下面是結果:
enter image description here

但是,當我使用Python腳本我沒有一個問題:
enter image description here

規格:

  • 操作系統:Ubuntu的14.04
  • CPU:i7-2600 3.50GHz
  • RAM:8GB

OpenCV ver。 3.0.0

*我說一些像素,約300萬像素。

編輯
下面是其餘的代碼。問題中的這一部分在保存裁剪後的圖像之前就已經過了。
http://pastebin.com/49rLhDcF
Mat outputImage = temp(Rect(lx,ty,abs(rx-lx),abs(by-ty)));

ps:因爲有很多像素,在生成大量圖像後,我得到分割錯誤(核心轉儲)。我知道這與記憶有關,我正在嘗試修復它,但我也希望聽到您的意見。

+1

'img_float.at (a,b);'< - a,b順序錯誤。 – berak

+2

可能你有'outputImage'是一個三通道矩陣。你以某種方式弄亂了1個通道圖像和3個通道圖像。更多的代碼可以幫助.. – Miki

+0

@Miki這裏是源代碼 http://pastebin.com/49rLhDcF 我只是今天改變它並運行它。我將在週一應用所有這些變化。 到目前爲止,問題中的代碼在保存修改後的(裁剪後的)圖像之前進行。 – Stefan

回答

0

問題解決了,
我只是補充了這幾行。

我用高斯模糊來平滑整個圖片,然後我複製了原始像素的值來預製我想要的效果。

for(int j = 0; j < pixels_gray.size(); j++) { 
       int x = pixels_gray[j].x; 
       int y = pixels_gray[j].y; 
       int lx = pixels_gray[j].lx; 
       int rx = pixels_gray[j].rx; 
       int ty = pixels_gray[j].ty; 
       int by = pixels_gray[j].by; 

       Mat outputImage = image_original(Rect(lx, ty, abs(rx - lx), abs(by-ty))); 

       Mat mask = Mat::ones(Size(90,90), CV_8UC1) * 255; 
       CvPoint  c = cvPoint(45, 45); 
       circle(mask, c, 30, 0, -1); 

       Mat smooth; 

       for (int i=1; i<11; i=i+2){ 
        GaussianBlur(outputImage, smooth, Size(i, i), 0, 0); 
       } 


       for(int my = 0; my < 90; my++){ 
        for(int mx = 0; mx <90; mx++){ 
         Scalar colour = mask.at<uchar>(Point(mx, my)); 
         if(colour.val[0]==255) continue; 
         smooth.at<Vec3b>(my,mx)[0] = outputImage.at<Vec3b>(my,mx)[0]; 
         smooth.at<Vec3b>(my,mx)[1] = outputImage.at<Vec3b>(my,mx)[1]; 
         smooth.at<Vec3b>(my,mx)[2] = outputImage.at<Vec3b>(my,mx)[2]; 
        } 
       } 


       stringstream ss; 
       ss << dir << "gray_" << y << "_" << x << ".png"; 
       imwrite(ss.str(), smooth, compression_params); 


      } 
相關問題