我是做图像的,原来都是用VC里现成的东西来做,但是现在人家要求我重新定义一个图像格式,可是定义完了之后的图像处理速度很慢,而且所有的图像(2值,灰度,真彩)处理速度基本上都一样。人家说不行,说2值应该是彩色的1/3左右,但是我不知道2值为什么会比彩色慢的原因,所以不知道怎么改,希望大家指点~!小女子不胜感激~!

解决方案 »

  1.   

    二值图像每个象素只用1位表示,彩色的需要至少8位,乃至32位
    二值处理的速度比彩色的快的原因也只能如此
    但是也要看是如何处理的
    比如查找边界的时候,二值也许比彩色的更慢呢,因为要从byte数据当中解释出来具体的位来,没有直接用byte判断快。图像处理的一些基本算法和代码可以在这里看到:http://www-scf.usc.edu/~flv/ipbook/
      

  2.   

    两者相比,二值不好的地方在于位提取上(彩色的也有这种可能,比如rgb565这种格式要提取红绿蓝的时候也是要位运算的),好的地方就是存储量小从磁盘读取的时候当然要快一些,因为二值化的存储量小啊不能绝对定义优劣,看具体的要求了对于旋转来说,差不多,这种操作的时间主要在定位算法上
    插值的时候颜色提取都有可能用到位操作的,没准谁快,24或者32位的比2值快,16和256的比2值慢。
      

  3.   

    可是我感觉已经没什么可以改了啊~!
    我用我的算法进行旋转,二值的图像(2136*2848)旋转时间为4.254132S,算很慢么?对了忘了说了,我用的是C#,很麻烦,不像原来用VC里面位图的格式,什么文件头之类都定义好了的,在这里要自己定义。而且读进来的时候要转换为我们公司自定义的图像格式,之后在旋转,之后显示的时候还要借助Bitmap(因为现在还没开发出来怎么直接显示)。 我的速度很慢么?
    值得一说的是原来用VC写的时候同样的东西为什么不到1S就出来了~!很郁闷~!
      

  4.   

    那怎么能快啊?
    我的程序是读文件时扫描1次,旋转扫描1次,把自定义文件转化为Bitmap扫描1次,显示扫描1次。
    相同的算法用Bitmap直接做,相当于扫描3次,需要时间更长啊~!要十几秒:(
      

  5.   

    算法的问题?
    for(int i=0;i<vout_Image.PixelInfo.Length;i++)
    {
          vout_Image.PixelInfo[i].Mono = 0;
    }
    int           PX,PY,k1,k2;        
    int           in_OX,in_OY;    
    int           out_OX,out_OY;   
    double        radRotate;       
    double        cosA, sinA;                          in_OX   = vin_Image.Width     / 2;
    in_OY   = vin_Image.Height    / 2;
    out_OX  = vout_Image.Width    / 2;
    out_OY  = vout_Image.Height   / 2;radRotate = angle / 57.2957795;
    cosA =Math.Cos(radRotate * (-1));
    sinA =Math.Sin(radRotate * (-1));     
    for (int  j = 0;j < vout_Image.Height ; j++ )
    {
            for (int i = 0;i < vout_Image.Width ;i++ )
    {
    pointcolor pc= vin_Image.GetPixel(i,j); PX = i - in_OX;                                              
    PY = j - in_OY;                                               k1 = (int)( ( PX * cosA - PY * sinA ) + in_OX );              
    k2 = (int)( ( PX * sinA + PY * cosA ) + in_OY );                  

    if(k1>0&k1<vin_Image.Width&k2>0&k2< vin_Image.Height)             
    { if(pc.Mono ==1)
    vout_Image.PixelInfo [(vout_Image.Height -k2-1)*vout_Image.Width +k1].Mono =1;
    else
    vout_Image.PixelInfo [(vout_Image.Height -k2-1)*vout_Image.Width +k1].Mono =0;
    }

    }
    }
      

  6.   

    我服了你了,小姐,图象不是这么做的!
    你看看你的程序,为了一个像素,有N个判断,N个成法,N个超级慢的三角函数,加减与不及其数,竟然还一个函数调用.读写方式也违背WRITEBACK的CPU缓存规则.
    我的基于指针的类似算法像素循环里只有2,3个计算,都是加减之类的快指令,速度保守估计也比你要快几十倍.不过我的程序比你的长得多,至少5倍以上.只不过我的旋转和你的规则不太相同,给你也没用.
    简单的说,你要把复杂计算搬到像素循环外面,尽量按写像素X方向做底层循环
      

  7.   

    唉,首先我得承认C#我没玩过,那也得避免vin_Image.GetPixel(i,j)这种东西,一个CALL几十个CPU时钟就出去了,在C里面就是直接计算地址,避免用乘法,(y*w+x)的办法很傻,用地址步进的办法.
    另外你先根据角度计算一个tg,根据斜率在原图象中走斜线,取得的像素在新图象中走水平横线,这样CPU的CACHE负担比较轻.
    不要每个点做好几个是否在范围内的判断,先找到扫描线中第一个和最后一个在范围内的像素,再做FOR循环
      

  8.   

    我想你的二值图也是8-bit的二值图吧,并不是真正意义上的1-bit的二值图!
    之所以要你的二值图旋转比彩图旋转快,是因为彩图的旋转要在同一点上计算三个值!而二值图只需要计算一个值!
      

  9.   

    超级同意 BadEnglish(BadEnglish)的说法,
    使用vin_Image.GetPixel(i,j)和vout_Image.PixelInfo 太慢了.
    没有用过java不知道是否可以用DIB来直接获得图像数据.会快很多
      

  10.   

    没有用过C#,不过相信里面有些函数还是不要直接调用,用某些API自己写比较好!
    建议:循环里面整个计算太多,特别是乘除;CPU计算里面乘除比较耗费指令周期,最好改变算法,除法最好改乘法或者加减;还有什么正弦余弦之类的更是耗费时间(可能是利用级数实现的),建议事先计算一些数值做好做个表格,查表实现(不过可能耗费内存多些)。
    浅见,仅供参考,没有代码。