精华内容
下载资源
问答
  • 图像变换--灰度切割、位图切割

    千次阅读 2013-12-06 16:26:25
    灰度切割:分为两种情况,一种情况是将某段阈值的图像设为一个较高值,其它灰度指定一个较低值。另一种情况是所需范围的灰度变亮,但仍保持图像的背景和灰度色调。 for (int i = 0; i  {  for (int j = 0; j  ...

    灰度切割:分为两种情况,一种情况是将某段阈值的图像设为一个较高值,其它灰度指定一个较低值。另一种情况是所需范围的灰度变亮,但仍保持图像的背景和灰度色调。

    for (int i = 0; i < img_height - 1; i++)
      {
       for (int j = 0; j < img_width - 1; j++)
       {
        uchar cur = data[i * img_width + j];

        if (cur > 20 && cur < 200)
        {
         cur  = cur + 50;
         if (cur < 0)
         {
          cur =0;
         }
         else if(cur > 255)
         {
          cur =255;
         }
         data[i * img_width + j] = cur;
        }
       }
      }

    位图切割:就8比物图像的位平面抽取而主,说明用一个灰度阈值变换函数处理输入图像可以获得位平面7的二值图像并不困难。该灰度阈值变换函数:(1)把图像中0和127间的所有灰度映射到一个灰度级例如(0)(2)把129到255间的灰度映射为另一种灰度级。例如(255)

    #include "math.h"
    #include"cv.h"
    #include"highgui.h"


    int main(int argc,char **argv)

     IplImage *pImg;
     IplImage *pImg_gray;
     IplImage *pImg_cut[8];
     

     if(argc == 3 && (pImg = cvLoadImage(argv[1],-1))!= 0)
     { 
      
      pImg_gray = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);


      cvCopy(pImg,pImg_gray,NULL);
      
      int img_width = pImg->width;//image width
      int img_height = pImg->height;//image height

      uchar *data;
      data = (uchar *)pImg_gray->imageData;
      uchar *data_cut[8];
      pImg_cut[0] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[1] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[2]= cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[3] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[4] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[5] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[6] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[7] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U,1);

      
      uchar zhi = 1;
      for (int k = 0; k< 8 ;k++)
      {
       data_cut[k] = (uchar *)pImg_gray->imageData;
       if (k > 0)
        zhi = zhi<<1;
       for (int i = 0; i< img_height; i++)
       {
        for (int j = 0; j< img_width ; j++)
        {
          uchar cur = data[i * img_width + j];
             cur = cur & 0x40; //按位与运算
          if (cur == 1)
          {
           cur = 255;
          }
          else cur = 0;
          data[i * img_width + j] = cur;
         
        }

       }
       cvCopy(pImg_gray,pImg_cut[k],NULL);
       cvCopy(pImg,pImg_gray,NULL);
       

      }

      cvNamedWindow("log1",1);//create window
      cvNamedWindow("log2",2);//create window
      cvNamedWindow("log3",3);//create window
      cvNamedWindow("log4",4);//create window
      cvNamedWindow("log5",5);//create window
      cvNamedWindow("log6",6);//create window
      cvNamedWindow("log7",7);//create window
      cvNamedWindow("log8",8);//create window

      cvShowImage("log1", pImg_cut[0]);
      cvShowImage("log2", pImg_cut[1]);
      cvShowImage("log3", pImg_cut[2]);
      cvShowImage("log4", pImg_cut[3]);
      cvShowImage("log5", pImg_cut[4]);
      cvShowImage("log6", pImg_cut[5]);
      cvShowImage("log7", pImg_cut[6]);
      cvShowImage("log8", pImg_cut[7]);

      cvWaitKey(0);

      cvDestroyWindow("canny");

      cvReleaseImage(&pImg);
      cvReleaseImage(&pImg_gray);
      
      return 0;
     }
     
     return -1;
    }

     

     


     

     


    #include "math.h"
    #include"cv.h"
    #include"highgui.h"
    //#include <iostream>
    //using namespace std;


    int main(int argc,char **argv)
    {
     /*IplImage *img=cvLoadImage("F:\HU\testopencv\pp.jpg");
     cvNamedWindow("Example1",CV_WINDOW_AUTOSIZE);
     cvShowImage("Example1",img);
     cvWaitKey(0);
     cvReleaseImage(&img);
     cvDestroyWindow("Example1"); */
     //图像反转
     IplImage *pImg;
     IplImage *pImg_gray;
     IplImage *pImg_cut[8];
     /*IplImage *pImg_cut0;
     IplImage *pImg_cut1;
     IplImage *pImg_cut2;
     IplImage *pImg_cut3;
     IplImage *pImg_cut4;
     IplImage *pImg_cut5;
     IplImage *pImg_cut6;
     IplImage *pImg_cut7;*/
     /*pImg_cut0 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut1 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut2 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut3 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut4 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut5 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut6 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     pImg_cut7 = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);*/
     //IplImage *pImg_bi;
     

     if(argc == 3 && (pImg = cvLoadImage(argv[1],-1))!= 0)
     { 
      
      pImg_gray = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
     // cvCvtColor(pImg,pImg_gray,CV_BGR2GRAY);
      cvCopy(pImg,pImg_gray,NULL);
      //pImg_bi = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      //cvThreshold(pImg_gray,pImg_bi,127,255  ,CV_THRESH_BINARY);
      //int a = pImg_bi->nChannels;
      //int bi_width = pImg_bi->
      int img_width = pImg->width;//image width
      int img_height = pImg->height;//image height

      uchar *data;
      data = (uchar *)pImg_gray->imageData;
      uchar *data_cut[8];
      pImg_cut[0] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[1] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[2]= cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[3] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[4] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[5] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[6] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);
      pImg_cut[7] = cvCreateImage(cvGetSize(pImg), IPL_DEPTH_8U, 1);

     /*  //for (int i = 0; i < img_height - 1; i++)
      //{
      // for (int j = 0; j < img_width - 1; j++)
      // {
      //  uchar cur = data[i * img_width + j];
      //   
      //  //cur =  3 * log((double)cur + 1.0);
      //  cur =  6 * sqrt((float)cur);
      //  if (cur < 0)
      //  {
      //   cur =0;
      //  }
      //  else if(cur > 255)
      //  {
      //   cur =255;
      //  }
      // }
      //}
      //line trans func线性变换
      float ratio = -3;//斜率
      float intercept = -838;//截距

      for (int i = 0; i < img_height - 1; i++)
      {
       for (int j = 0; j < img_width - 1; j++)
       {
        uchar cur = data[i * img_width + j];
        /*cur = ratio * cur + intercept;//线性变换

        data[i * img_width + j] = cur;
        if (cur < 0)
        {
         cur =0;
        }
        else if(cur > 255)
        {
         cur =255;
        }*/
       /* if (cur > 20 && cur < 200)
        {
         cur  = cur + 50;
         if (cur < 0)
         {
          cur =0;
         }
         else if(cur > 255)
         {
          cur =255;
         }
         data[i * img_width + j] = cur;
        }
       }
      }*/

      /*for (int i = 0; i< img_height -1 ; i++)
      {
      for (int j = 0; j< img_width -1; j++)
      {
      printf("%d",data[i * img_width + j]);
      }
      printf("\n");
      }*/
    //  cvSaveImage(argv[2],pImg_bi);
      uchar zhi = 1;
      for (int k = 0; k< 8 ;k++)
      {
       data_cut[k] = (uchar *)pImg_gray->imageData;
       if (k > 0)
        zhi = zhi<<1;
       for (int i = 0; i< img_height; i++)
       {
        for (int j = 0; j< img_width ; j++)
        {
          uchar cur = data[i * img_width + j];
             cur = cur & 0x40; //按位与运算
          if (cur == 1)
          {
           cur = 255;
          }
          else cur = 0;
          data[i * img_width + j] = cur;
         
        }

       }
       cvCopy(pImg_gray,pImg_cut[k],NULL);
       cvCopy(pImg,pImg_gray,NULL);
       

      }

      cvNamedWindow("log1",1);//create window
      cvNamedWindow("log2",2);//create window
      cvNamedWindow("log3",3);//create window
      cvNamedWindow("log4",4);//create window
      cvNamedWindow("log5",5);//create window
      cvNamedWindow("log6",6);//create window
      cvNamedWindow("log7",7);//create window
      cvNamedWindow("log8",8);//create window

      cvShowImage("log1", pImg_cut[0]);
      cvShowImage("log2", pImg_cut[1]);
      cvShowImage("log3", pImg_cut[2]);
      cvShowImage("log4", pImg_cut[3]);
      cvShowImage("log5", pImg_cut[4]);
      cvShowImage("log6", pImg_cut[5]);
      cvShowImage("log7", pImg_cut[6]);
      cvShowImage("log8", pImg_cut[7]);

      cvWaitKey(0);

      cvDestroyWindow("canny");

      cvReleaseImage(&pImg);
      cvReleaseImage(&pImg_gray);
      //cvReleaseImage(&pImg_bi);
      return 0;
     }
     //printf("%s\n %s\n%s\n", argv[0],argv[1],argv[2]);
     return -1;
    }

     

     


     

     

     

    展开全文
  • 灰度变换,属于一个非常重要的概念。这里主要参考《Digital Image Processing》 Rafael C. Gonzalez / Richard E. Woods 的第三章。书中所有的实验与数学式都采用了8-bit 图像的灰度范围,也就是0到255这样一个范围...
    灰度变换,属于一个非常重要的概念。这里主要参考《Digital Image Processing》 Rafael C. Gonzalez / Richard E. Woods 的第三章。书中所有的实验与数学式都采用了8-bit 图像的灰度范围,也就是0到255这样一个范围,这是本书不合理的一个地方。首先,这样做并不泛用,图片不一定是8-bit的。其次,在做某些变换的时候,可能会导致溢出。比如,伽马变化,假设伽马值为2,那么灰度为255的像素点,其变换之后值为65025,这里就溢出了。当然,要是使用Matlab计算,肯定会处理的非常好,直接使用mat2gray函数就能将其压缩回0到255。但是要是其他嵌入式平台处理的时候,直接套用不方便不说,直接按照8-bit的图来理解很不直观。因此,我将数学式做了改变,让其输入为0到1的浮点数,其输出也是0到1的浮点数,这样方便理解。 
    

          本文所使用的图片,均来源于《Digital Image Processing》的主页 http://www.imageprocessingplace.com/

           图像反转

           图像反转,这个翻译还是很不恰当的。这里应该理解为负片变换,负片变换如下所示。

    负片变换,主要用于观察过黑的图片,负片变换之后,方便观察。很简单的变换。

           对数变换

           对数变换主要用于将图像的低灰度值部分扩展,将其高灰度值部分压缩,以达到强调图像低灰度部分的目的。变换方法由下式给出。

    这里的对数变换,底数为,实际计算的时候,需要用换底公式。其输入为,其输出也为。对于不同的底数,其对应的变换曲线如下图所示。

    底数越大,对低灰度部分的强调就越强,对高灰度部分的压缩也就越强。相反的,如果想强调高灰度部分,则用反对数函数就可以了。看下面的实验就可以很直观的理解,下图是某图像的二维傅里叶变换图像,其为了使其灰度部分较为明显,一般都会使用灰度变换处理一下。

           实现对数变换的Matlab代码如下:
    1. close all;  
    2. clear all;  
    3.   
    4. %% -------------Log Transformations-----------------  
    5. f = imread('DFT_no_log.tif');  
    6. f = mat2gray(f,[0 255]);  
    7.   
    8. v = 10;  
    9. g_1 = log2(1 + v*f)/log2(v+1);  
    10.   
    11. v = 30;  
    12. g_2 = log2(1 + v*f)/log2(v+1);  
    13.   
    14. v = 200;  
    15. g_3 = log2(1 + v*f)/log2(v+1);  
    16.   
    17. figure();  
    18. subplot(1,2,1);  
    19. imshow(f,[0 1]);  
    20. xlabel('a).Original Image');  
    21. subplot(1,2,2);  
    22. imshow(g_1,[0 1]);  
    23. xlabel('b).Log Transformations v=10');  
    24.   
    25. figure();  
    26. subplot(1,2,1);  
    27. imshow(g_2,[0 1]);  
    28. xlabel('c).Log Transformations v=100');  
    29.   
    30. subplot(1,2,2);  
    31. imshow(g_3,[0 1]);  
    32. xlabel('d).Log Transformations v=200');  
    close all;
    clear all;
    
    %% -------------Log Transformations-----------------
    f = imread('DFT_no_log.tif');
    f = mat2gray(f,[0 255]);
    
    v = 10;
    g_1 = log2(1 + v*f)/log2(v+1);
    
    v = 30;
    g_2 = log2(1 + v*f)/log2(v+1);
    
    v = 200;
    g_3 = log2(1 + v*f)/log2(v+1);
    
    figure();
    subplot(1,2,1);
    imshow(f,[0 1]);
    xlabel('a).Original Image');
    subplot(1,2,2);
    imshow(g_1,[0 1]);
    xlabel('b).Log Transformations v=10');
    
    figure();
    subplot(1,2,1);
    imshow(g_2,[0 1]);
    xlabel('c).Log Transformations v=100');
    
    subplot(1,2,2);
    imshow(g_3,[0 1]);
    xlabel('d).Log Transformations v=200');

           伽马变换

           伽马变换主要用于图像的校正,将漂白的图片或者是过黑的图片,进行修正。伽马变换也常常用于显示屏的校正,这是一个非常常用的变换。其变化所用数学式如下所示,

    其输入为,其输出也为对于不同的伽马值,其对应的变换曲线如下图所示。

    和对数变换一样,伽马变换可以强调图像的某个部分。根据下面两个实验,可以看出伽马变换的作用。
           实验1:

    其实现Matlab代码为:
    1. close all;  
    2. clear all;  
    3.   
    4. %% -------------Gamma Transformations-----------------  
    5. f = imread('fractured_spine.tif');  
    6. f = mat2gray(f,[0 255]);  
    7.   
    8. C = 1;  
    9. Gamma = 0.4;  
    10. g2 = C*(f.^Gamma);  
    11.   
    12. figure();  
    13. subplot(1,2,1);  
    14. imshow(f,[0 1]);  
    15. xlabel('a).Original Image');  
    16.   
    17. subplot(1,2,2);  
    18. imshow(g2,[0 1]);  
    19. xlabel('b).Gamma Transformations \gamma = 0.4');  
    close all;
    clear all;
    
    %% -------------Gamma Transformations-----------------
    f = imread('fractured_spine.tif');
    f = mat2gray(f,[0 255]);
    
    C = 1;
    Gamma = 0.4;
    g2 = C*(f.^Gamma);
    
    figure();
    subplot(1,2,1);
    imshow(f,[0 1]);
    xlabel('a).Original Image');
    
    subplot(1,2,2);
    imshow(g2,[0 1]);
    xlabel('b).Gamma Transformations \gamma = 0.4');
           实验2:

           灰度拉伸

           灰度拉伸也用于强调图像的某个部分,与伽马变换与对数变换不同的是,灰度拉升可以改善图像的动态范围。可以将原来低对比度的图像拉伸为高对比度图像。实现灰度拉升的方法很多,其中最简单的一种就是线性拉伸。而这里介绍的方法稍微复杂一些。灰度拉伸所用数学式如下所示。

    同样的,其输入为,其输出也为。这个式子再熟悉不过了,跟巴特沃斯高通滤波器像极了,其输入输出关系也大致能猜到是个什么形状的。但是,这里就出现一个问题了,输入为0时候,式子无意义了。所以,在用Matlab计算的时候,将其变为如下形式。

    这里的eps,就是Matlab里面,一个很小数。如此做的话,式子变得有意义了。但是,其输入范围为的时候,其输出范围变为了。输出范围大致为,为了精确起见,使用mat2gray函数将其扩展到精确的。调用格式如下。
    1. g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);  
    g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);
           输入输出问题解决了,还有一个问题,参数的决定。这里有两个参数,一个是m(相对于巴特沃斯高通滤波器而言,这个是截止频率),一个是E(相对于巴特沃斯高通滤波器而言,这个是滤波器次数)。m可以控制变换曲线的重心,E则可以控制曲线的斜率,如下图所示。

    m值的可取图像灰度分布的中央值,如下式所示,

           决定m之后,接下来就只剩E了。灰度拉升的目的就是扩展图片的动态范围,我们想将原本灰度范围是的图像变换到内。那么,就直接取最大值与最小值,带入式子,解出E就可以了。但是,如之前所说的,我们所用的式子的的输出范围达不到,而且,直接取的范围,会造成E非常大,从而变换曲线的斜率非常大,灰度扩展的结果并不是很好。所以,这里退一步,取的输出范围是。E的取值,如下所示。

           实验:

           从直方图看,原图的灰度范围确实被拉伸了。用上面所说的方法,确定的灰度拉伸的输入输出曲线如下图所示。

          其Matlab代码如下:
    1. close all;  
    2. clear all;  
    3.   
    4. %% -------------Contrast Stretching-----------------  
    5. f = imread('washed_out_pollen_image.tif');  
    6. %f = imread('einstein_orig.tif');  
    7. f = mat2gray(f,[0 255]);  
    8.   
    9. [M,N] = size(f);  
    10. g = zeros(M,N);  
    11.   
    12. Min_f = min(min(f));  
    13. Max_f = max(max(f));  
    14. m = (Min_f + Max_f)/2;  
    15.   
    16. Out_put_min = 0.05;  
    17. Out_put_max = 0.95;  
    18.   
    19. E_1 = log(1/Out_put_min - 1)/log(m/(Min_f+eps));  
    20. E_2 = log(1/Out_put_max - 1)/log(m/(Max_f+eps));  
    21. E = ceil(min(E_1,E_2)-1);  
    22.   
    23. g = 1 ./(1 + (m ./ (f+ eps)).^E);  
    24. g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);  
    25.   
    26. figure();  
    27. subplot(2,2,1);  
    28. imshow(f,[0 1]);  
    29. xlabel('a).Original Image');  
    30.   
    31. subplot(2,2,2);  
    32. r = imhist(f)/(M*N);  
    33. bar(0:1/255:1,r);  
    34. axis([0 1 0 max(r)]);  
    35. xlabel('b).The Histogram of a');  
    36. ylabel('Number of pixels');  
    37.   
    38. subplot(2,2,3);  
    39. imshow(g,[0 1]);  
    40. xlabel('c).Results of Contrast stretching');  
    41.   
    42. subplot(2,2,4);  
    43. s = imhist(g)/(M*N);  
    44. bar(0:1/255:1,s);  
    45. axis([0 1 0 max(s)]);  
    46. xlabel('b).The Histogram of a');  
    47. ylabel('Number of pixels');  
    48.   
    49. in_put = 0:1/255:1;  
    50. Out_put1 = 1 ./(1 + (m ./ (double(in_put)+ eps)).^E);  
    51. Out_put1 = mat2gray(Out_put1,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);  
    52.   
    53. figure();  
    54. plot(in_put,Out_put1);  
    55. axis([0,1,0,1]),grid;  
    56. axis square;  
    57. xlabel('Input intensity level');  
    58. ylabel('Onput intensity level');  
    close all;
    clear all;
    
    %% -------------Contrast Stretching-----------------
    f = imread('washed_out_pollen_image.tif');
    %f = imread('einstein_orig.tif');
    f = mat2gray(f,[0 255]);
    
    [M,N] = size(f);
    g = zeros(M,N);
    
    Min_f = min(min(f));
    Max_f = max(max(f));
    m = (Min_f + Max_f)/2;
    
    Out_put_min = 0.05;
    Out_put_max = 0.95;
    
    E_1 = log(1/Out_put_min - 1)/log(m/(Min_f+eps));
    E_2 = log(1/Out_put_max - 1)/log(m/(Max_f+eps));
    E = ceil(min(E_1,E_2)-1);
    
    g = 1 ./(1 + (m ./ (f+ eps)).^E);
    g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);
    
    figure();
    subplot(2,2,1);
    imshow(f,[0 1]);
    xlabel('a).Original Image');
    
    subplot(2,2,2);
    r = imhist(f)/(M*N);
    bar(0:1/255:1,r);
    axis([0 1 0 max(r)]);
    xlabel('b).The Histogram of a');
    ylabel('Number of pixels');
    
    subplot(2,2,3);
    imshow(g,[0 1]);
    xlabel('c).Results of Contrast stretching');
    
    subplot(2,2,4);
    s = imhist(g)/(M*N);
    bar(0:1/255:1,s);
    axis([0 1 0 max(s)]);
    xlabel('b).The Histogram of a');
    ylabel('Number of pixels');
    
    in_put = 0:1/255:1;
    Out_put1 = 1 ./(1 + (m ./ (double(in_put)+ eps)).^E);
    Out_put1 = mat2gray(Out_put1,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);
    
    figure();
    plot(in_put,Out_put1);
    axis([0,1,0,1]),grid;
    axis square;
    xlabel('Input intensity level');
    ylabel('Onput intensity level');

           灰度切割

           灰度切割也是一个很简单,但也很实用的变换。灰度切割,主要用于强调图像的某一部份,将这个部分赋为一个较高的灰度值,其变换对应关系如下所示。

    灰度切割有以上两种方法,一种是特定灰度值的部分赋值为一个较高的灰度值,其余部分为一个较低的灰度值。这样的方法,得到的结果是一个二值化图像。另外一种方法,则是仅仅强调部分赋值为一个较高的灰度值,其余的部分不变。
           实验:

           位图切割

           位图切割,就是按照图像的位,将图像分层处理。若图像的某个像素,其bit7为1,则在位面7这个像素值为1,反之则为0。
           实验:

           由位图切割的结果,图像的主要信息包含在了高4位。仅仅靠高4位,还原的图像更原图基本差不多。由此可见,位图切割主要用于图像压缩。
    展开全文
  • 灰度切割和位图切割的区别Description: 描述: In this article we are going to see how to maximize profit by cutting rod with dynamic programming? This is a classic DP problem featured in many ...

    灰度切割和位图切割的区别

    Description:

    描述:

    In this article we are going to see how to maximize profit by cutting rod with dynamic programming? This is a classic DP problem featured in many interview rounds of Amazon, Samsung etc.

    在本文中,我们将看到如何通过动态编程切杆来最大化利润? 这是许多亚马逊,三星等采访中都提到的经典DP问题。

    Problem statement:

    问题陈述:

    Given a rod of length N inches and an array of prices that contains prices for all pieces of size smaller than n. Determine the maximum value obtainable by cutting up the rod and selling the pieces.

    给定一根长度为N英寸的棒,并包含一组价格,其中包含所有小于n的尺寸的价格。 确定通过切割杆并出售零件可获得的最大值。

        Input:
        First input line consists of N, 
        denoting the size of array. 
        Second line of price of ith length piece.
        
        Output:
        Print maximum price that can be obtained by selling the pieces.
    
    

    Example:

    例:

        Input:
        Length of rod: 8
    
        Prices of pieces:
        1 5 6 9 12 15 13 20
    
        Output:
        maximum price that can be obtained: 20
    
    

    Explanation:

    说明:

    Let us first understand the input format

    首先让我们了解输入格式

    Each element in the array represent price of length i where i is the index (considering 1-indexing).

    数组中的每个元素代表长度为i的价格,其中i为索引(考虑1索引)。

    So, for the above example:

    因此,对于上面的示例:

        Price of length 1: 1  (arr[0])
        Price of length 2: 5  (arr[1])
        Price of length 3: 6  (arr[2])
        Price of length 4: 9  (arr[3])
        Price of length 5: 12 (arr[4])
        Price of length 6: 15 (arr[5])
        Price of length 7: 13 (arr[6])
        Price of length 8: 20 (arr[7])
    
    

    Now, the thing is cutting the rod recursively. Like you have to option;

    现在,事情正在递归地切断杆。 就像你必须选择;

    1. Cut of ith length and recur for remaining

      减少 i 长度,然后重复剩余

    2. Else don't cut of that length.

      否则不要减少长度。

    The recursive function can be written as:

    递归函数可以写成:

        f(n) = maximum (f(i)+f(n-i))  where 1 ≤ i< n
    
    

    In the above example, it's found that if we don't cut into pieces, if we sell the whole rod as 1 piece, then it would maximize profit to 20. All other options will lead to less amount of profit.

    在上面的示例中,发现如果不切成小块,如果将整根棒子出售为1个,那么它将使利润最大化到20。所有其他选择将导致更少的利润。

    Also, if we make 4 pieces of length 2, would have same profit, 20.

    另外,如果我们制作4个长度为2的片段,则将获得相同的利润20。

    Solution Approach:

    解决方法:

    Let's convert the above recursion in to dynamic programing.

    让我们将上述递归转换为动态编程。

    The sub-problem can be to solve for rod of length i where 1<=i<=n and we need to store the results of this sub-problems in a array, namely DP

    子问题可以是求解长度为i的棒,其中1 <= i <= n ,我们需要将此子问题的结果存储在数组中,即DP

    1. Declare DP[n+1]

      声明DP [n + 1]

    2. DP[0]=0 as the result for rod length 0 is 0.

      DP [0] = 0 ,因为杆长度0的结果为0。

    3. Now we need to calculate DP[i] which would be results for rod length i (subproblems)

      现在我们需要计算DP [i] ,这将是杆长度i (子问题)的结果

    4. As a base case, initialize DP[i] with arr[i-1] which is the result if we don't cut into smaller pieces and sell the whole rod(piece of length i).

      作为基本情况,用arr [i-1]初始化DP [i] ,如果我们不切成小块并出售整根棒(长度为i的块),则结果为。

      for(int i=1;i<=n;i++)
          dp[i]=a[i-1];
      
      The reason behind 
      dp[i]=arr[i-1] not dp [i] = arr [i-1]而不是arr[i] because in DP array we are following 1-indexing( like for arr [i]的原因是因为在DP数组中,我们遵循1-indexing(就像对于n=1 it's n = 1,它是DP[1]) and for arr we are following 0-indexing(for DP [1] ),对于arr,我们遵循0-indexing (对于n=1, n = 1arr[0]) arr [0] )
    5. Now, calculate DP[i] which will be maximum profit for sub problem with length i

      现在,计算DP [i] ,它将是长度为i的子问题的最大利润

      Here we will use the recursive relation mentioned above

      这里我们将使用上面提到的递归关系

      To calculate

      计算

      DP[i],for 2≤i≤n,

      DP [i] ,对于2≤i≤n

      if

      如果

      i is 1 that follows base case,no more pieces to cut down

      是跟随基本情况的1,不再需要削减

          for j=1 to i-1
              dp[i]=maximum(dp[j]+dp[i-j])
          end for
      
      
    6. DP[n] is the final result which is maximum profit for rod length n.

      DP [n]是最终结果,它是杆长度n的最大利润。

    We could have calculated through the recursive function, but needless to say that the recursion tree would have overlapping sub-problem resulting to exponential time complexity. Hence, we converted the recursion into DP and solved.

    我们可以通过递归函数进行计算,但是不用说,递归树将具有重叠的子问题,从而导致指数的时间复杂度。 因此,我们将递归转换为DP并求解。

    C++ Implementation:

    C ++实现:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int rodcutting(vector < int > a, int n) {
      int dp[n + 1];
      dp[0] = 0;
    
      for (int i = 1; i <= n; i++)
        dp[i] = a[i - 1];
      for (int i = 2; i <= n; i++) {
        for (int j = 1; j < i; j++) {
          if (dp[i] < dp[j] + dp[i - j])
            dp[i] = dp[j] + dp[i - j];
        }
      }
      return dp[n];
    }
    
    int main() {
      int n, item;
    
      cout << "Enter rod length:\n";
      scanf("%d", & n);
      cout << "Enter prices for the pieces of ith length:\n";
      vector < int > a;
      for (int j = 0; j < n; j++) {
        scanf("%d", & item);
        a.push_back(item);
      }
    
      cout << "Maximum profit can be earned is: " << rodcutting(a, n) << endl;
    
      return 0;
    }
    
    

    Output

    输出量

    RUN 1:
    Enter rod length: 
    8
    Enter prices for the pieces of ith length:
    1 5 6 9 12 15 13 20
    Maximum profit can be earned is: 20
    
    RUN 2:
    Enter rod length: 
    7
    Enter prices for the pieces of ith length:
    4 5 6 3 21 15 13 
    Maximum profit can be earned is: 29
    
    
    

    翻译自: https://www.includehelp.com/icp/rod-cutting.aspx

    灰度切割和位图切割的区别

    展开全文
  • [数字图像处理]灰度变换——反转,对数变换,伽马变换,灰度拉伸,灰度切割,位图切割 【From】http://blog.csdn.net/zhoufan900428/article/details/12709361 数字图像处理灰度变换灰度拉伸MATLAB...

    [数字图像处理]灰度变换——反转,对数变换,伽马变换,灰度拉伸,灰度切割,位图切割

    【From】http://blog.csdn.net/zhoufan900428/article/details/12709361

    目录(?)[+]

                灰度变换,属于一个非常重要的概念。这里主要参考《Digital Image Processing》 Rafael C. Gonzalez / Richard E. Woods 的第三章。书中所有的实验与数学式都采用了8-bit 图像的灰度范围,也就是0到255这样一个范围,这是本书不合理的一个地方。首先,这样做并不泛用,图片不一定是8-bit的。其次,在做某些变换的时候,可能会导致溢出。比如,伽马变化,假设伽马值为2,那么灰度为255的像素点,其变换之后值为65025,这里就溢出了。当然,要是使用Matlab计算,肯定会处理的非常好,直接使用mat2gray函数就能将其压缩回0到255。但是要是其他嵌入式平台处理的时候,直接套用不方便不说,直接按照8-bit的图来理解很不直观。因此,我将数学式做了改变,让其输入为0到1的浮点数,其输出也是0到1的浮点数,这样方便理解。

          本文所使用的图片,均来源于《Digital Image Processing》的主页 http://www.imageprocessingplace.com/

           图像反转

           图像反转,这个翻译还是很不恰当的。这里应该理解为负片变换,负片变换如下所示。

    负片变换,主要用于观察过黑的图片,负片变换之后,方便观察。很简单的变换。

           对数变换

           对数变换主要用于将图像的低灰度值部分扩展,将其高灰度值部分压缩,以达到强调图像低灰度部分的目的。变换方法由下式给出。

    这里的对数变换,底数为,实际计算的时候,需要用换底公式。其输入为,其输出也为。对于不同的底数,其对应的变换曲线如下图所示。

    底数越大,对低灰度部分的强调就越强,对高灰度部分的压缩也就越强。相反的,如果想强调高灰度部分,则用反对数函数就可以了。看下面的实验就可以很直观的理解,下图是某图像的二维傅里叶变换图像,其为了使其灰度部分较为明显,一般都会使用灰度变换处理一下。

           实现对数变换的Matlab代码如下:
    [plain]  view plain copy
    1. close all;  
    2. clear all;  
    3.   
    4. %% -------------Log Transformations-----------------  
    5. f = imread('DFT_no_log.tif');  
    6. f = mat2gray(f,[0 255]);  
    7.   
    8. v = 10;  
    9. g_1 = log2(1 + v*f)/log2(v+1);  
    10.   
    11. v = 30;  
    12. g_2 = log2(1 + v*f)/log2(v+1);  
    13.   
    14. v = 200;  
    15. g_3 = log2(1 + v*f)/log2(v+1);  
    16.   
    17. figure();  
    18. subplot(1,2,1);  
    19. imshow(f,[0 1]);  
    20. xlabel('a).Original Image');  
    21. subplot(1,2,2);  
    22. imshow(g_1,[0 1]);  
    23. xlabel('b).Log Transformations v=10');  
    24.   
    25. figure();  
    26. subplot(1,2,1);  
    27. imshow(g_2,[0 1]);  
    28. xlabel('c).Log Transformations v=100');  
    29.   
    30. subplot(1,2,2);  
    31. imshow(g_3,[0 1]);  
    32. xlabel('d).Log Transformations v=200');  

           伽马变换

           伽马变换主要用于图像的校正,将漂白的图片或者是过黑的图片,进行修正。伽马变换也常常用于显示屏的校正,这是一个非常常用的变换。其变化所用数学式如下所示,

    其输入为,其输出也为。对于不同的伽马值,其对应的变换曲线如下图所示。

    和对数变换一样,伽马变换可以强调图像的某个部分。根据下面两个实验,可以看出伽马变换的作用。
           实验1:

    其实现Matlab代码为:
    [plain]  view plain copy
    1. close all;  
    2. clear all;  
    3.   
    4. %% -------------Gamma Transformations-----------------  
    5. f = imread('fractured_spine.tif');  
    6. f = mat2gray(f,[0 255]);  
    7.   
    8. C = 1;  
    9. Gamma = 0.4;  
    10. g2 = C*(f.^Gamma);  
    11.   
    12. figure();  
    13. subplot(1,2,1);  
    14. imshow(f,[0 1]);  
    15. xlabel('a).Original Image');  
    16.   
    17. subplot(1,2,2);  
    18. imshow(g2,[0 1]);  
    19. xlabel('b).Gamma Transformations \gamma = 0.4');  
           实验2:

           灰度拉伸

           灰度拉伸也用于强调图像的某个部分,与伽马变换与对数变换不同的是,灰度拉升可以改善图像的动态范围。可以将原来低对比度的图像拉伸为高对比度图像。实现灰度拉升的方法很多,其中最简单的一种就是线性拉伸。而这里介绍的方法稍微复杂一些。灰度拉伸所用数学式如下所示。

    同样的,其输入为,其输出也为。这个式子再熟悉不过了,跟巴特沃斯高通滤波器像极了,其输入输出关系也大致能猜到是个什么形状的。但是,这里就出现一个问题了,输入为0时候,式子无意义了。所以,在用Matlab计算的时候,将其变为如下形式。

    这里的eps,就是Matlab里面,一个很小数。如此做的话,式子变得有意义了。但是,其输入范围为的时候,其输出范围变为了。输出范围大致为,为了精确起见,使用mat2gray函数将其扩展到精确的。调用格式如下。
    [plain]  view plain copy
    1. g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);  
           输入输出问题解决了,还有一个问题,参数的决定。这里有两个参数,一个是m(相对于巴特沃斯高通滤波器而言,这个是截止频率),一个是E(相对于 巴特沃斯高通滤波器而言,这个是滤波器次数)。m可以控制变换曲线的重心,E则可以控制曲线的斜率,如下图所示。

    m值的可取图像灰度分布的中央值,如下式所示,

           决定m之后,接下来就只剩E了。灰度拉升的目的就是扩展图片的动态范围,我们想将原本灰度范围是的图像变换到内。那么,就直接取最大值与最小值,带入式子,解出E就可以了。但是,如之前所说的,我们所用的式子的的输出范围达不到,而且,直接取的范围,会造成E非常大,从而变换曲线的斜率非常大,灰度扩展的结果并不是很好。所以,这里退一步,取的输出范围是。E的取值,如下所示。

           实验:

           从直方图看,原图的灰度范围确实被拉伸了。用上面所说的方法,确定的灰度拉伸的输入输出曲线如下图所示。

          其Matlab代码如下:
    [plain]  view plain copy
    1. close all;  
    2. clear all;  
    3.   
    4. %% -------------Contrast Stretching-----------------  
    5. f = imread('washed_out_pollen_image.tif');  
    6. %f = imread('einstein_orig.tif');  
    7. f = mat2gray(f,[0 255]);  
    8.   
    9. [M,N] = size(f);  
    10. g = zeros(M,N);  
    11.   
    12. Min_f = min(min(f));  
    13. Max_f = max(max(f));  
    14. m = (Min_f + Max_f)/2;  
    15.   
    16. Out_put_min = 0.05;  
    17. Out_put_max = 0.95;  
    18.   
    19. E_1 = log(1/Out_put_min - 1)/log(m/(Min_f+eps));  
    20. E_2 = log(1/Out_put_max - 1)/log(m/(Max_f+eps));  
    21. E = ceil(min(E_1,E_2)-1);  
    22.   
    23. g = 1 ./(1 + (m ./ (f+ eps)).^E);  
    24. g = mat2gray(g,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);  
    25.   
    26. figure();  
    27. subplot(2,2,1);  
    28. imshow(f,[0 1]);  
    29. xlabel('a).Original Image');  
    30.   
    31. subplot(2,2,2);  
    32. r = imhist(f)/(M*N);  
    33. bar(0:1/255:1,r);  
    34. axis([0 1 0 max(r)]);  
    35. xlabel('b).The Histogram of a');  
    36. ylabel('Number of pixels');  
    37.   
    38. subplot(2,2,3);  
    39. imshow(g,[0 1]);  
    40. xlabel('c).Results of Contrast stretching');  
    41.   
    42. subplot(2,2,4);  
    43. s = imhist(g)/(M*N);  
    44. bar(0:1/255:1,s);  
    45. axis([0 1 0 max(s)]);  
    46. xlabel('b).The Histogram of a');  
    47. ylabel('Number of pixels');  
    48.   
    49. in_put = 0:1/255:1;  
    50. Out_put1 = 1 ./(1 + (m ./ (double(in_put)+ eps)).^E);  
    51. Out_put1 = mat2gray(Out_put1,[1/(1+(m/eps)^E) 1/(1+(m/1+eps)^E)]);  
    52.   
    53. figure();  
    54. plot(in_put,Out_put1);  
    55. axis([0,1,0,1]),grid;  
    56. axis square;  
    57. xlabel('Input intensity level');  
    58. ylabel('Onput intensity level');  

           灰度切割

           灰度切割也是一个很简单,但也很实用的变换。灰度切割,主要用于强调图像的某一部份,将这个部分赋为一个较高的灰度值,其变换对应关系如下所示。

    灰度切割有以上两种方法,一种是特定灰度值的部分赋值为一个较高的灰度值,其余部分为一个较低的灰度值。这样的方法,得到的结果是一个二值化图像。另外一种方法,则是仅仅强调部分赋值为一个较高的灰度值,其余的部分不变。
           实验:

           位图切割

           位图切割,就是按照图像的位,将图像分层处理。若图像的某个像素,其bit7为1,则在位面7这个像素值为1,反之则为0。
           实验:

           由位图切割的结果,图像的主要信息包含在了高4位。仅仅靠高4位,还原的图像更原图基本差不多。由此可见,位图切割主要用于图像压缩。
    展开全文
  • 灰度图像阈值分割

    2018-11-18 15:32:27
    用于实现灰度图像阈值分割的二维最大熵方法,使用matlab实现
  • Matlab实现灰度图m*n分割

    千次阅读 2020-05-08 00:43:24
    end 运行效果为: 输入: 输出: 3 问题总结 3.1 灰度图与彩色图 最开始我只使用了imread(),没有转灰度图,所以得到的img的RGB图的结构,对其操作就出现了错误。 3.2 高维矩阵降维 注意,在matlab中,若A是一个333...
  • 灰度图像阈值化分割常见方法总结及VC实现 分类:图像处理OpenCV2011-11-11 23:20609人阅读评论(11)收藏举报 在图像处理领域,二值图像运算量小,并且能够体现图像的关键特征,因此被广泛使用。将灰度图像变为...
  • K-Means 算法是应用最为广泛的聚类算法[2]。该算法以类中各样本的加权均值(称为质心)代表该类,只用于数字属性数据的 聚类,全局阈值分割,对图像的分割还挺好的,不利用直方图,
  • # 【将图像灰度化,转换成灰度图】 image = cv . cvtColor ( image , cv . COLOR_BGR2GRAY ) # 【显示图像】 cv . imshow ( 'win' , image ) cv . waitKey ( 0 ) 参考文章1:【OpenCV3经典编程100例...
  • java图像处理方法:灰度化,二值化,降噪,切割,裁剪,找相似等
  • 灰度图像--图像分割 综合介绍

    千次阅读 2015-02-05 10:14:34
    并且可以准确的把肉夹到嘴里,而在灰度图中,信息没有人眼捕捉到的多,灰度图像分割多半依靠区域的灰度变化,产生一系列的算法和应用。  本文作为分割的基本介绍,首先会给出分割的基本知识结构,此结构不唯一,...
  • 运行代码: % 最大图像尺寸 128 x 128 I=imread('Lenna.jpg'); 垫=3; MAXVAL = 255; [Ncut] = graphcuts(I,pad,MAXVAL) % 函数 [Ncut] = graphcuts(I) % 输入:I 图像% pad:空间连通性; 例如。...
  • matlab对图像处理——裁剪 获取灰度图 获取坐标点

    千次阅读 多人点赞 2019-04-16 22:52:08
    建立循环函数,通过程序依此读取十幅原始图像,然后将原始图像转存为灰度图像 确定数码管所显示数字的四角坐标,然后将其依次输出 依据之前寻找到的四个坐标,将数字部分以外的图像设置为黑色; 在(3...
  • 伪彩色增强 由于人眼对彩色的分辨...实现方法:亮度切割法、灰度级彩色变换法、频域滤波法 这里我们直接调用cv2库中函数实现亮度切割 void cv::applyColorMap(InputArray src,OutputArray dst,int colormap) src Th
  • 基于Python的车牌识别(切割及识别)

    万次阅读 多人点赞 2019-12-07 18:48:46
    基于Python的车牌识别(切割及识别) 上一篇博文简单的分享车牌定位,这次,将定位出来的车牌进行分割并识别出该字符。 1、车牌定位及提取 可参考上一篇博文,下方是提取出来的车牌 1、车牌二值化 def split_char...
  • 灰度化:在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫做灰度值,因此,灰度图像每个像素值只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。 二值化:二值化可以把灰度图片...
  • 本文针对规则切割的汉字碎纸片的拼接复原,通过读取碎纸片的灰度值,进行二值化处理,建立规则切割的汉字碎纸片的拼接复原模型,对二值图像矩阵与对应的列矩阵、边缘矩阵的处理,结合人工干预,获得正确的图片顺序,...
  • 此代码是对灰度图像使用归一化切割的图切割分割的不言自明的实现,如 Shi、Jianbo 和 Jitendra Malik 所述。 “标准化切割和图像分割。” 模式分析和机器智能,IEEE Transactions on 22.8 (2000): 888-905。 该代码...
  • 灰度处理 增加对比度(可选) 二值化 降噪 倾斜校正分割字符 建立训练库 识别 由于是实验性质的,文中用到的验证码均为程序生成而不是批量下载真实的网站验证码,这样做的好处就是可以有大量的知道明确结果的...
  • 灰度图像变为二值图像的常用方法是选定阈值,然后将待处理图像的每个像素点进行单点处理,即将其灰度值与所设置的门限进行比对,从而得到二值化的黑白图。这样一种方式因为其直观性以及易于实现,已经在图像分割...
  • 灰度级:0~255 ==》256个灰度级 层次:图像实际拥有灰度级的数量 对比度:灰度反差的大小 二值图像(binary image):图像上的每一个像素只有两种可能的取值或灰度等级状态。每个像素只需要1Bit就可以完整存储...
  • 建立边缘识别用抛物线模型,根据边缘处存在灰度特征、梯度特征和方向特征设计识别目标函数,识别切割顶点两侧边缘,进而识别整个切割点处的几何形状。实验表明识别方法具有良好的适应性、准确性和实时性。
  • 灰度图像增强和图像去噪

    万次阅读 2016-01-17 21:11:04
    P1 图像灰度变换增强... 2 一、  前言... 2 二、  灰度变换增强的方法及其实现... 2 1.  线性灰度变换... 2 2.  分段线性灰度变换... 4 3.  对数函数灰度变换... 6 4.  反对数函数灰度变换... 8 5.  伽马变换...
  • 基于matlab的图像处理,灰度共生方法实现图像切割,六个指标都要,非常适合初学者学习

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,735
精华内容 1,894
关键字:

灰度切割