我要用C#实现对图像的缩放、鼠标拖曳和灰度拉伸等功能,且图像可能非常大,请问我该使用picturebox控件吗

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我要用C#实现对图像的缩放、鼠标拖曳和灰度拉伸等功能,且图像可能非常大,请问我该使用picturebox控件吗相关的知识,希望对你有一定的参考价值。

我的图像格式是tiff或者RAW的,非常大,用picturebox控件会不会导致内存不足啊,不用能实现吗,应该采用什么类来实现比较好呢?我是新手,希望多指教!不胜感激!
我需要用自己的算法对tiff和RAW文件的每个像素进行操作从而进行缩放和拉伸,主要难点是怎么处理tiff和RAW这两种文件格式,希望有过这方面经验的前辈多指教!先谢了!

参考技术A 当然可以用Picturebox来装图片,如果图片很多的话建议还是不要放太多个的picturebox,可以试试Imagelist来装载,然后证书取每一张就让picturebox显示。追问

谢谢,我现在的问题是不知道怎么处理tif和RAW这两种文件格式~~

参考技术B wpf hlsl 百度之
基于hlsl的高级着色语言就是使用像素着色器进行处理像素,其流程就是对每个像素自己操作。,并且是在显卡执行,能有效解决性能问题,至于你说的文件大,可以使用内存映射文件,速度绝对有保障追问

谢谢,不过可能我没说明白,我主要的问题在于怎么处理tif和RAW这两种文件格式~~

追答

使用FormatConvertedBitmap bitmap = new FormatConvertedBitmap();

参考技术C 这个据说要用opencv技术来处理,那个我没怎么研究过没,给你个参考链接
for C#

参考资料:http://blog.csdn.net/caiye917015406/article/details/7267467

来自:求助得到的回答本回答被提问者采纳
参考技术C 可以的。追问

你好,能不能说详细点啊,最佳选择是用什么实现呢

追答

picturebox 这个控件就是用来放图片的。我想问一下你这个到底是要实现什么效果呢?

追问

我大概知道picturebox的用途,我想实现对图像的缩放和鼠标拖曳,不过我图像非常大,且对缩放要求比较高,我还需要把缩放后的数据发送出去,我怕内存不够!

追答

这个控件可以实现对于图片的拖拽和缩放。至于发送,我建议还是用发送文件的方式。

图像的点运算----底层代码与Halcon库函数

       最基本的图像分析工具----灰度直方图。使用直方图辅助,可以实现4大灰度变换,包括线性灰度变换(灰度拉伸)、灰度对数变换、灰度伽马变换、灰度分段线性变换;使用直方图修正技术,可以实现2大变换,包括直方图均衡化和直方图规定化。

一、灰度直方图

        灰度直方图分为一般灰度直方图和归一化灰度直方图,灰度直方图统计图像中各个灰度级出现的次数,而归一化的灰度直方图统计的是各个灰度级出现的频率。因此,灰度直方图通常在定量上,有总体像素个数以及各个灰度像素个数;在定性上,可以看出整体灰度动态范围,即对比度与亮度。

       使用C#绘制一般灰度直方图的底层代码中,算法流程的核心是计算各个灰度级的像素个数;而绘制归一化灰度直方图,算法流程的核心是计算灰度即的累积分布函数。代码如下,然而代码在Halcon库中,可随意查看。

  byte* Init_byte = (byte*)bmpdata.Scan0;
                //必须先对行遍历,再对列遍历
                for (int i = 0; i < bmpdata.Height; i++)
                {
                    for (int j = 0; j < bmpdata.Width; j++)
                    {
                        //计算出不同灰度级的像素个数
                        temp = *Init_byte;
                        CountPix[temp]++;
                 //换列
                        Init_byte++;
                    }
                 //换行
                    Init_byte += bmpdata.Stride - bmpdata.Width;
                }
                for (int k = 0; k < 256; k++)
                {
                    //计算出不同灰度级的累积像素个数
                    if (k!=0)
                    {
                        CumulatePix[k] = CumulatePix[k - 1] + CountPix[k];
                    }
                    else
                    {
                        CumulatePix[0] = CountPix[0];
                    }
                }

 

      二、灰度的线性与非线性变换

        灰度变换的目的在于增强图像的灰度对比度,达到理想预处理的目的。线性灰度变换,使用C#编码核心在于遍历图像的所有像素,对每个像素点添加一个乘性系数以及一个加性系数,调节两个参数以达到预想的效果(注意:对越界数值进行处理(0-255));非线性灰度变换,有对数变换与指数变换、伽马变换以及分段变换,编码实现同理,但区别在于实现了图像灰度的扩展和压缩功能,它会扩展低灰度值而压缩高灰度值,或者相反,让图像的灰度分布更加符合人的视觉特征或灰度对比度更强。在Halcon中,对应算子分别是scale_image、scale_image_max、log_image、exp_image、pow_image,分段变换则比较麻烦了,一般使用overpaint_region对图像中的region进行变换。因此,分段变换适合在底层实现。

  unsafe
            {
                byte* Init_byte = (byte*)mbpdata.Scan0;
                for (int i = 0; i < mbpdata.Width; i++)
                {
                    for (int j = 0; j < mbpdata.Height; j++)
                    {
                        value = k * (*Init_byte) + b;
                     //处理越界值
                        if (value>255)
                        {
                            *Init_byte = 255;
                        }
                        else if (value<0)
                        {
                            *Init_byte = 0;
                        }
                        else
                        {
                            *Init_byte = (byte)value;
                        }
                        
                        Init_byte++;
                    }
                    Init_byte += mbpdata.Stride - mbpdata.Width;
                }
            }

 

    三、直方图均衡与直方图规定化

        直方图均衡是以累积分布函数变换为基础的直方图修正法,可以产生灰度级为概率均匀分布的图像。主要用于增强动态范围偏小的图像,以提升灰度对比度。使用C#编码的核心算法流程,1.将灰度值进行归一化;2.将图像灰度设置概率均匀分布,即p=1。图像归一化就是将图像转换成唯一的标准形式以抵抗各种变换,并在此基础上进行灰度均匀分布。

      因此,当原始图像的直方图不同而图像结构性内容相同时,直方图均衡化所得到的视觉上几乎是完全一致的。而后,学者相继提出自适应的直方图均衡化算法(AHE)以及对比度有限的自适应直方图均衡化(CLAHE)。而去雾算法的本质是对图像对比度和亮度的调节,因此,CLAHE广泛应用在去雾算法中。

       在Halcon中,直方图均衡化只是一句代码的事,equ_histo_image。

   byte* Init_byte = (byte*)bmpdata.Scan0;
                //必须先对行遍历,再对列遍历
                for (int i = 0; i < bmpdata.Height; i++)
                {
                    for (int j = 0; j < bmpdata.Width; j++)
                    {
                        //计算出不同灰度级的像素个数
                        temp = *Init_byte;
                        CountPix[temp]++;
                        Init_byte++;
                    }
                    Init_byte += bmpdata.Stride - bmpdata.Width;
                }
                for (int k = 0; k < 256; k++)
                {
                    //计算出不同灰度级的累积像素个数
                    if (k!=0)
                    {
                        CumulatePix[k] = CumulatePix[k - 1] + CountPix[k];
                    }
                    else
                    {
                        CumulatePix[0] = CountPix[0];
                    }
                    //根据灰度值进行一对一映射,其中注意运算法顺序和括号,防止只出现整数0.
                    PixMap[k] = (byte)(255 *CumulatePix[k] / bytes+0.5);
                }
                byte* Init_byte2 = (byte*)bmpdata.Scan0;
                for (int i = 0; i < bmpdata.Height; i++)
                {
                    for (int j = 0; j < bmpdata.Width; j++)
                    {
                        //直方图均衡化,获取灰度级,对应映射
                        temp = *Init_byte2;
                        *Init_byte2=PixMap[temp];
                        Init_byte2++;
                    }
                    Init_byte += bmpdata.Stride - bmpdata.Width;
                }

        直方图均衡化不仅操作简单且有效地丰富灰度级,但这个过程是不受控制的,因此引出了直方图规定化,或称直方图匹配。直方图规定化本质上是一种拟合过程,因此使规定化图像在对比度以及亮度上具有类似标准图像的特性,这也正是直方图规定化的目的所在。直方图规定化的算法流程是建立在直方图均衡化之上的,统计累积分布概率的最小差值的位置,进行一一对应的映射。

      

以上是关于我要用C#实现对图像的缩放、鼠标拖曳和灰度拉伸等功能,且图像可能非常大,请问我该使用picturebox控件吗的主要内容,如果未能解决你的问题,请参考以下文章

matlab中灰度图像矩阵的大小问题怎么操作?

对比度拉伸(一些基本的灰度变换函数)基本原理及Python实现

如何在 C# windows 窗体中绘制可缩放图像

如何用matlab减小图像的灰度级别

MATLAB教程案例21图像的初步认识,通过MATLAB对图像进行简单操作——读写缩放二值图直方图灰度图色度空间转化等

图像的点运算----底层代码与Halcon库函数