精华内容
下载资源
问答
  • 灰度图像二值化处理

    2018-06-20 18:11:38
    图像灰度化处理算法,涵盖几种经典二值化算法的实现,如:灰度平均值,黄氏模糊阈值,谷底最小值,等13中二值化阈值选择方法
  • 【数字图像处理灰度图像二值化

    千次阅读 2019-10-08 00:56:27
    灰度图像 每副图像的每个像素对应二维空间中一个特定的位置,并且有一个或者多...灰度图像二值化 二值化:以一个值(阈值)为基准,大于(等于)这个值的数全部变为是1(或者0),小于等于这个数的就全部将他们变...

     

    灰度图像

    每副图像的每个像素对应二维空间中一个特定的位置,并且有一个或者多个与那个点相关的采样值组成数值。

    灰度图像,也称为灰阶图像,图像中每个像素可以由0(黑)到255(白)的亮度值(Intensity)表示。0-255之间表示不同的灰度级。

     

    灰度图像二值化

    二值化:以一个值(阈值)为基准,大于(等于)这个值的数全部变为是1(或者0),小于等于这个数的就全部将他们变为0(或1)。

    二值化算法处理飞思卡尔赛道思路:设定一个阈值valve,对于图像矩阵中的每一行,从左至右比较各像素值和阈值的大小,若像素值大于或等于阈值,则判定该像素对应的是白色赛道;反之,则判定对应的是黑色的目标引导线。

    记下第一次和最后一次出现像素值小于阈值时的像素点的列号,算出两者的平均值,以此作为该行上目标引导线的位置。

    摄像头的二值化的代码:

     
    
    Void image_binaryzation()
    
    {
    
    for(int i=0;i
    
    {
    
        for(int j=0;j
    
        {
    
    if(Image[i][j] >= Threshold)
    
           Image_new[i][j]=1;
    
    else
    
        Image_new[i][j]=0;
    
        }
    
    }
    
    }

    Row是对应采集到的行数,Col是列数,Image[i][j]是摄像头采集未二值化的数据存放的数组,Img[i][j]是新建的存放二值化后的数组。

     

    合适的阈值

    在阈值二值化中,最主要的是选取合适的阈值,这也是二值化的难点所在。常用的二值化阈值选取方法有双峰法、p参数法、大律法(Otsu法)、最大熵阈值法、迭代法等。

    大律法(Otsu法)

    Otsu方法又名最大类间差方法,通过统计整个图像的直方图特性来实现全局阈值T的自动选取,其算法步骤为:
    1) 先计算图像的直方图,即将图像所有的像素点按照0~255共256个bin,统计落在每个bin的像素点数量
    2) 归一化直方图,也即将每个bin中像素点数量除以总的像素点
    3) i表示分类的阈值,也即一个灰度级,从0开始迭代
    4) 通过归一化的直方图,统计0~i 灰度级的像素(假设像素值在此范围的像素叫做前景像素) 所占整幅图像的比例w0,并统计前景像素的平均灰度u0;统计i~255灰度级的像素(假设像素值在此范围的像素叫做背景像素) 所占整幅图像的比例w1,并统计背景像素的平均灰度u1;
    5) 计算前景像素和背景像素的方差 g = w0*w1*(u0-u1) (u0-u1)
    6) i++;转到4),直到i为256时结束迭代
    7)将最大g相应的i值作为图像的全局阈值
    缺陷:OSTU算法在处理光照不均匀的图像的时候,效果会明显不好,因为利用的是全局像素信息。
    解决光照不均匀:https://blog.csdn.net/kk55guang2/article/details/78475414
                  https://blog.csdn.net/kk55guang2/article/details/78490069
                  https://wenku.baidu.com/view/84e5eb271a37f111f0855b2d.html
    ***************************************************************/ 
    int GetOSTU(uint8_t tmImage[Use_ROWS][Use_Line]) 
    { 
    /**
      * @brief    未优化过的大津法
      *
      * @param    运算时间比较长
      *
      * @return   实测120*160的图像
      *
      * @note     K66 220MHz需要9ms
      *
      * @example  
      *
      * @date     2019/4/16 星期二
      */
    //    int width = Use_ROWS;
    //    int height = Use_Line;
    //    int x = 0, y = 0;
    //    int pixelCount[256];
    //    float pixelPro[256];
    //    int i, j, pixelSum = width * height, threshold = 0;
    //    
    //    
    //    //初始化
    //    for (i = 0; i < 256; i++)
    //    {
    //        pixelCount[i] = 0;
    //        pixelPro[i] = 0;
    //    }
    //    
    //    //统计灰度级中每个像素在整幅图像中的个数
    //    for (i = y; i < height; i++)
    //    {
    //        for (j = x; j <width; j++)
    //        {
    //            pixelCount[tmImage[i][j]]++;
    //        }
    //    }
    //    
    //    //计算每个像素在整幅图像中的比例
    //    for (i = 0; i < 256; i++)
    //    {
    //        pixelPro[i] = (float)(pixelCount[i]) / (float)(pixelSum);
    //    }
    //    
    //    //经典ostu算法,得到前景和背景的分割
    //    //遍历灰度级[0,255],计算出方差最大的灰度值,为最佳阈值
    //    float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;
    //    for (i = 0; i < 256; i++)
    //    {
    //        w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
    //        
    //        for (j = 0; j < 256; j++)
    //        {
    //            if (j <= i) //背景部分
    //            {
    //                //以i为阈值分类,第一类总的概率
    //                w0 += pixelPro[j];
    //                u0tmp += j * pixelPro[j];
    //            }
    //            else       //前景部分
    //            {
    //                //以i为阈值分类,第二类总的概率
    //                w1 += pixelPro[j];
    //                u1tmp += j * pixelPro[j];
    //            }
    //        }
    //        
    //        u0 = u0tmp / w0;        //第一类的平均灰度
    //        u1 = u1tmp / w1;        //第二类的平均灰度
    //        u = u0tmp + u1tmp;        //整幅图像的平均灰度
    //        //计算类间方差
    //        deltaTmp = w0 * (u0 - u)*(u0 - u) + w1 * (u1 - u)*(u1 - u);
    //        //找出最大类间方差以及对应的阈值
    //        if (deltaTmp > deltaMax)
    //        {
    //            deltaMax = deltaTmp;
    //            threshold = i;
    //        }
    //    }
    //    //返回最佳阈值;
    //    return threshold;
        
    /**
      * @brief    优化过的大津法
      *
      * @param    大大减少运算时间
      *
      * @return   实测K66 220MHz 120*160的图像
      *
      * @note     只需要1.5ms
      *
      * @example  未优化的大津法需要9ms
      *
      * @date     2019/4/16 星期二
      */ 
        int16_t i,j; 
        uint32_t Amount = 0; 
        uint32_t PixelBack = 0; 
        uint32_t PixelIntegralBack = 0; 
        uint32_t PixelIntegral = 0; 
        int32_t PixelIntegralFore = 0; 
        int32_t PixelFore = 0; 
        float OmegaBack, OmegaFore, MicroBack, MicroFore, SigmaB, Sigma; // 类间方差; 
        int16_t MinValue, MaxValue; 
        uint8_t Threshold = 0;
        uint8_t HistoGram[256];              //  
        
        for (j = 0; j < 256; j++)  HistoGram[j] = 0; //初始化灰度直方图 
        
        for (j = 0; j < Use_ROWS; j++) 
        { 
            for (i = 0; i < Use_Line; i++) 
            { 
                HistoGram[tmImage[j][i]]++; //统计灰度级中每个像素在整幅图像中的个数
            } 
        } 
        
        for (MinValue = 0; MinValue < 256 && HistoGram[MinValue] == 0; MinValue++) ;        //获取最小灰度的值
        for (MaxValue = 255; MaxValue > MinValue && HistoGram[MinValue] == 0; MaxValue--) ; //获取最大灰度的值
        
        if (MaxValue == MinValue)      return MaxValue;         // 图像中只有一个颜色    
        if (MinValue + 1 == MaxValue)  return MinValue;         // 图像中只有二个颜色
        
        for (j = MinValue; j <= MaxValue; j++)    Amount += HistoGram[j];        //  像素总数
        
        PixelIntegral = 0;
        for (j = MinValue; j <= MaxValue; j++)
        {
            PixelIntegral += HistoGram[j] * j;//灰度值总数
        }
        SigmaB = -1;
        for (j = MinValue; j < MaxValue; j++)
        {
            PixelBack = PixelBack + HistoGram[j];   //前景像素点数
            PixelFore = Amount - PixelBack;         //背景像素点数
            OmegaBack = (float)PixelBack / Amount;//前景像素百分比
            OmegaFore = (float)PixelFore / Amount;//背景像素百分比
            PixelIntegralBack += HistoGram[j] * j;  //前景灰度值
            PixelIntegralFore = PixelIntegral - PixelIntegralBack;//背景灰度值
            MicroBack = (float)PixelIntegralBack / PixelBack;   //前景灰度百分比
            MicroFore = (float)PixelIntegralFore / PixelFore;   //背景灰度百分比
            Sigma = OmegaBack * OmegaFore * (MicroBack - MicroFore) * (MicroBack - MicroFore);//计算类间方差
            if (Sigma > SigmaB)                    //遍历最大的类间方差g //找出最大类间方差以及对应的阈值
            {
                SigmaB = Sigma;
                Threshold = j;
            }
        }
        return Threshold;                        //返回最佳阈值;
    } 

    可以参考文献

    https://wenku.baidu.com/view/acc24dcf680203d8ce2f2469.html

    https://wenku.baidu.com/view/bb6e38f7c8d376eeaeaa3163.html

     

    二值化图像去噪

    对于二值化图像而言,去除噪声是很重要的一步。

    思路:对任意像素点判断是否为0,取得该像素点周围8个或者四个像素点相加,总和等于255 * 8或者 255 *4,则说明该像素点为噪声,置为255。

    注意:领域的计算方法是没有边界的,所以通常不计算图像四边。

                int bai;
                        for(int i = 1; i < Use_ROWS-1; i++)   
                        {
                            for(int j =1; j < Use_Line-1; j++)
                            { if(Image_Use[i-1][j] == 255) continue;     
                              bai = Image_Use[i-1][j] + Image_Use[i-1][j-1] + Image_Use[i-1][j+1] +Image_Use[i][j+1] +Image_Use[i][j-1] +Image_Use[i+1][j] +Image_Use[i+1][j-1] +Image_Use[i+1][j+1] ;
                              if(bai == 2040)
                              Image_Use[i][j] = 255;
                              
                            }
                        }

     

    转载于:https://www.cnblogs.com/-wenli/p/11486877.html

    展开全文
  • 灰度图像二值化 一、知识简介 图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。 在数字图像处理中,二值图像占有非常重要的地位,图像...

    灰度图像二值化

    一、知识简介

    图像二值化( Image Binarization)就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的黑白效果的过程。
    在数字图像处理中,二值图像占有非常重要的地位,图像的二值化使图像中数据量大为减少,从而能凸显出目标的轮廓。

    二、灰度图像二值化原理

    当灰度图像的像素值大于某个阈值时将该灰度值设置为最大 反之设置为最小,此时灰度图只有最亮和最黑。

    1、将RGB值转化为[0,1]浮点数 或者[0,255]
    2、 二值化:

    if (img_gray[i, j] <= 0.5): 或者<=128

    img_gray[i, j] = 0

    else:

    img_gray[i, j] = 1

    三、python实现

    import cv2
    # 以灰度图的方式读取图片
    img_gray = cv2.imread("image0.JPG", 0)
    cv2.imshow("Scr", img_gray)
    cv2.waitKey(0)
    
    # 归一化(0,1)
    img_gray = img_gray / 255
    cv2.imshow("Normalization", img_gray)
    cv2.waitKey(0)
    
    # 二值化
    img_gray_h,img_gray_w = img_gray.shape
    for i in range(img_gray_h):
        for j in range(img_gray_w):
            if (img_gray[i][j] <= 0.5):
                img_gray[i][j] = 0
            else:
                img_gray[i][j] = 1
    
    cv2.imshow("Binarization", img_gray)
    cv2.waitKey(0)
    
    
    展开全文
  • c#图像处理之图形灰度二值化处理。通过读取图像,实现图像灰度化,二值化功能,并保存。
  • 为加快处理速度,在图像处理算法中,往往需要把彩色图像转换为灰度图像,在灰度图像上得到验证的算法,很容易移植到彩色图像上。24位彩色图像每个像素用3个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝)。当R、...

    为加快处理速度,在图像处理算法中,往往需要把彩色图像转换为灰度图像,在灰度图像上得到验证的算法,很容易移
    植到彩色图像上。
    24位彩色图像每个像素用3个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝)。当R、G、B分量值不同时,表现为彩色图像;当R、G、B分量值相同时,表现为灰度图像,该值就是我们所求的一般来说,转换公式有3种。第一种转换公式为:

    Gray(i,j)=[R(i,j)+G(i,j)+B(i,j)]÷3            (2.1)

    其中,Gray(i,j)为转换后的灰度图像在(i,j)点处的灰度值。该方法虽然简单,但人眼对颜色的感应是不同的,因此有了第二种转换公式:

    Gray(i,j)=0299R(i,j)+0.587×G(i,j)+0.114×B(i,j)      (2.2)

    观察上式,发现绿色所占的比重最大,所以转换时可以直接使用G值作为转换后的灰度

    Gray(i,j)=G(i,j)                    (2.3)

    在这里,我们应用最常用的公式(2.2),并且变换后的灰度图像仍然用24位图像表示。

     

    1.提取像素法

    这种方法简单易懂,但相当耗时,完全不可取.
    该方法使用的是GD+中的 Bitmap Getpixel和 BitmapSetpixel.方法。为了将位图的颜色设置为灰度或其他颜色,就需要使用 Gepiⅸxel来读取当前像素的颜色,再计算灰度值,最后使用 Setpixel来应用新的颜色。双击“提取像素法” Button控件,为该控件添加 Click事件,

    代码如下:

         /// <summary>
            /// 提取像素法
            /// </summary>
            private void pixel_Click(object sender, EventArgs e)
            {if (curBitmpap != null)
                {
                    Color curColor;
                    int ret;
    
                    //二维图像数组循环
                    for(int i = 0; i < curBitmpap.Width; i++)
                    {
                        for(int j = 0; j < curBitmpap.Height; j++)
                        {
                            //获取该像素点的RGB颜色值
                            curColor = curBitmpap.GetPixel(i, j);
                            //利用公式计算灰度值
                            ret = (int)(curColor.R * 0.299 + curColor.G * 0.587 + curColor.B * 0.114);
                            //设置该像素点的灰度值,R=G=B=ret
                            curBitmpap.SetPixel(i, j, Color.FromArgb(ret, ret, ret));
                        }
                    }//对窗体进行重新绘制,这将强制执行Paint事件处理程序
                    Invalidate();
                }
            }

     


    2.内存法
    该方法就是把图像数据直接复制到内存中,这样就使程序的运行速度大大提高。双击“内存法”按钮控件,为该控件添加Cick事件,代码如下:

         /// <summary>
            /// 内存法(适用于任意大小的24位彩色图像)
            /// </summary>
            private void memory_Click(object sender, EventArgs e)
            {if (curBitmpap != null)
                {
                    //位图矩形
                    Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height);
                    //以可读写的方式锁定全部位图像素
                    System.Drawing.Imaging.BitmapData bmpData = curBitmpap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmpap.PixelFormat);
                    //得到首地址
                    IntPtr ptr = bmpData.Scan0;
    
                    //定义被锁定的数组大小,由位图数据与未用空间组成的
                    int bytes = bmpData.Stride * bmpData.Height;
                    //定义位图数组
                    byte[] rgbValues = new byte[bytes];
                    //复制被锁定的位图像素值到该数组内
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
    
                    //灰度化
                    double colorTemp = 0;
                    for (int i = 0; i < bmpData.Height; i++)
                    {
                        //只处理每行中是图像像素的数据,舍弃未用空间
                        for (int j = 0; j < bmpData.Width * 3; j += 3)
                        {
                            //利用公式计算灰度值
                            colorTemp = rgbValues[i * bmpData.Stride + j + 2] * 0.299 + rgbValues[i * bmpData.Stride + j + 1] * 0.587 + rgbValues[i * bmpData.Stride + j] * 0.114;
                            //R=G=B
                            rgbValues[i * bmpData.Stride + j] = rgbValues[i * bmpData.Stride + j + 1] = rgbValues[i * bmpData.Stride + j + 2] = (byte)colorTemp;
                        }
                    }
    
                    //把数组复制回位图
                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
                    //解锁位图像素
                    curBitmpap.UnlockBits(bmpData);//对窗体进行重新绘制,这将强制执行Paint事件处理程序
                    Invalidate();
                }
            }

     

    3.指针法
    该方法与内存法相似,开始都是通过 Lockbits方法来获取位图的首地址。但该方法更简洁,直接应用指针对位图进行操作。

    为了保持类型安全,在默认情况下,C#是不支持指针运算的,因为使用指针会带来相关的风险。所以C#只允许在特别标记的代码块中使用指针。通过使用 unsafe关键字,可以定义可使用指针的不安全上下文。

    双击“指针法”按钮控件,为该控件添加 Click事件,代码如下:

         /// <summary>
            /// 指针法
            /// </summary>
            private void pointer_Click(object sender, EventArgs e)
            {if (curBitmpap != null)
                {
                    //位图矩形
                    Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height);
                    //以可读写的方式锁定全部位图像素
                    System.Drawing.Imaging.BitmapData bmpData = curBitmpap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmpap.PixelFormat);
    
                    byte temp = 0;
                    //启用不安全模式
                    unsafe
                    {
                        //得到首地址
                        byte* ptr = (byte*)(bmpData.Scan0);
                        //二维图像循环
                        for (int i = 0; i < bmpData.Height; i++)
                        {
                            for (int j = 0; j < bmpData.Width; j++)
                            {
                                //利用公式计算灰度值
                                temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
                                //R=G=B
                                ptr[0] = ptr[1] = ptr[2] = temp;
                                //指向下一个像素
                                ptr += 3;
                            }
                            //指向下一行数组的首个字节
                            ptr += bmpData.Stride - bmpData.Width * 3;
                        }
                    }
                    //解锁位图像素
                    curBitmpap.UnlockBits(bmpData);//对窗体进行重新绘制,这将强制执行Paint事件处理程序
                    Invalidate();
                }
            }

    由于启动了不安全模式,为了能够顺利地编译该段代码,必须设置相关选项。在主菜单中选择“项目|gray属性”,在打开的属性页中选择“生成”属性页,最后选中“允许不安全代码”复选框。

     

    三种方法的比较

    从3段代码的长度和难易程度来看,提取像素法又短又简单。它直接应用GD+中的Bitmap. Getpixel方法和 Bitmap. Setpixel方法,大大减少了代码的长度,降低了使用者的难度,并且可读性好。但衡量程序好坏的标准不是仅仅看它的长度和难易度,而是要看它的效率,尤其是像图像处理这种往往需要处理二维数据的大信息量的应用领域,就更需要考虑效率了为了比较这3种方法的效率,我们对其进行计时。首先在主窗体内添加一个 Label控件和 Textbox控件。

     

    添加一个类:HiPerfTimer

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.Threading;
    
    namespace gray
    {
        internal class HiPerfTimer
        {
            //引用win32API中的QueryPerformanceCounter()方法
            //该方法用来查询任意时刻高精度计数器的实际值
            [DllImport("Kernel32.dll")]         //using System.Runtime.InteropServices;
            private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
    
            //引用win32API中的QueryPerformanceCounter()方法
            //该方法用来查询任意时刻高精度计数器的实际值
            [DllImport("Kernel32.dll")]
            private static extern bool QueryPerformanceFrequency(out long lpFrequency);
    
            private long startTime, stopTime;
            private long freq;
    
            public HiPerfTimer()
            {
                startTime = 0;
                stopTime = 0;
    
                if(QueryPerformanceFrequency(out freq) == false)
                {
                    //不支持高性能计时器
                    throw new Win32Exception();     //using System.ComponentModel;
                }
            }
    
            //开始计时
            public void Start()
            {
                //让等待线程工作
                Thread.Sleep(0);                //using System.Threading;
    
                QueryPerformanceCounter(out startTime);
            }
            //结束计时
            public void Stop()
            {
                QueryPerformanceCounter(out stopTime);
            }
            //返回计时结果(ms)
            public double Duration
            {
                get
                {
                    return (double)(stopTime - startTime) * 1000 / (double)freq;
                }
            }
    
        }
    }

    在Form1类内定义HiPerfTimer类并在构造函数内为其实例化

            private HiPerfTimer myTimer;
            public Form1()
            {
                InitializeComponent();
                myTimer = new gray.HiPerfTimer();
            }

     

    分别在“提取像素法”、“内存法”和“指针法” Button控件的 Click事件程序代码内的

    if判断语句之间的最开始一行添加以下代码:

                //启动计时器
                myTimer.Start();

    在上述3个单击事件内的 Invalidate0语句之前添加以下代码:

                 //关闭计时器
                 myTimer.Stop();
                 //在TextBox内显示计时时间
                 timeBox.Text = myTimer.Duration.ToString("####.##") + "毫秒";

     

    最后,编译并运行该段程序。可以明显看出,内存法和指针法比提取像素法要快得多。提取像素法应用GDI+中的方法,易于理解,方法简单,很适合于C#的初学者使用,但它的运行速度最慢,效率最低。内存法把图像复制到内存中,直接对内存中的数据进行处理,速度明显提高,程序难度也不大。指针法直接应用指针来对图像进行处理,所以速度最快。但在C#中是不建议使用指针的,因为使用指针,代码不仅难以编写和调试,而且无法通过CLR的内存类型安全检查,不能发挥C#的特长。只有对C#和指针有了充分的理解,才能用好该方法。究竟要使用哪种方法,还要看具体情况而定。但3种方法都能有效地对图像进行处理。

     

    全文代码:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace gray
    {
        public partial class Form1 : Form
        {
            private HiPerfTimer myTimer;
            public Form1()
            {
                InitializeComponent();
                myTimer = new gray.HiPerfTimer();
            }
    
            //文件名
            private string curFileName;
            //图像对象
            private System.Drawing.Bitmap curBitmpap;
    
            /// <summary>
            /// 打开图像文件
            /// </summary>
            private void open_Click(object sender, EventArgs e)
            {
                //创建OpenFileDialog
                OpenFileDialog opnDlg = new OpenFileDialog();
                //为图像选择一个筛选器
                opnDlg.Filter = "所有图像文件|*.bmp;*.pcx;*.png;*.jpg;*.gif;" +
                    "*.tif;*.ico;*.dxf;*.cgm;*.cdr;*.wmf;*.eps;*.emf|" +
                    "位图(*.bmp;*.jpg;*.png;...)|*.bmp;*.pcx;*.png;*.jpg;*.gif;*.tif;*.ico|" +
                    "矢量图(*.wmf;*.eps;*.emf;...)|*.dxf;*.cgm;*.cdr;*.wmf;*.eps;*.emf";
                //设置对话框标题
                opnDlg.Title = "打开图像文件";
                //启用“帮助”按钮
                opnDlg.ShowHelp = true;
    
                //如果结果为“打开”,选定文件
                if(opnDlg.ShowDialog()==DialogResult.OK)
                {
                    //读取当前选中的文件名
                    curFileName = opnDlg.FileName;
                    //使用Image.FromFile创建图像对象
                    try
                    {
                        curBitmpap = (Bitmap)Image.FromFile(curFileName);
                    }
                    catch(Exception exp)
                    {
                        MessageBox.Show(exp.Message);
                    }
                }
                //对窗体进行重新绘制,这将强制执行paint事件处理程序
                Invalidate();
            }
    
            private void Form1_Paint(object sender, PaintEventArgs e)
            {
                //获取Graphics对象
                Graphics g = e.Graphics;
                if (curBitmpap != null)
                {
                    //使用DrawImage方法绘制图像
                    //160,20:显示在主窗体内,图像左上角的坐标
                    //curBitmpap.Width, curBitmpap.Height图像的宽度和高度
                    g.DrawImage(curBitmpap, 160, 20, curBitmpap.Width, curBitmpap.Height);
                }
            }
    
            /// <summary>
            /// 保存图像文件
            /// </summary>
            private void save_Click(object sender, EventArgs e)
            {
                //如果没有创建图像,则退出
                if (curBitmpap == null)
                    return;
    
                //调用SaveFileDialog
                SaveFileDialog saveDlg = new SaveFileDialog();
                //设置对话框标题
                saveDlg.Title = "保存为";
                //改写已存在文件时提示用户
                    saveDlg.OverwritePrompt = true;
                //为图像选择一个筛选器
                    saveDlg.Filter = "BMP文件(*.bmp)|*.bmp|" + "Gif文件(*.gif)|*.gif|" + "JPEG文件(*.jpg)|*.jpg|" + "PNG文件(*.png)|*.png";
                //启用“帮助”按钮
                    saveDlg.ShowHelp = true;
    
                //如果选择了格式,则保存图像
                if (saveDlg.ShowDialog() == DialogResult.OK)
                {
                    //获取用户选择的文件名
                    string filename = saveDlg.FileName;
                    string strFilExtn = filename.Remove(0, filename.Length - 3);
    
                    //保存文件
                    switch (strFilExtn)
                    {
                        //以指定格式保存
                        case "bmp":
                            curBitmpap.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp);
                            break;
                        case "jpg":
                            curBitmpap.Save(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
                            break;
                        case "gif":
                            curBitmpap.Save(filename, System.Drawing.Imaging.ImageFormat.Gif);
                            break;
                            case "tif":
                            curBitmpap.Save(filename, System.Drawing.Imaging.ImageFormat.Tiff);
                            break;
                        case "png":
                            curBitmpap.Save(filename, System.Drawing.Imaging.ImageFormat.Png);
                            break;
                        default:
                            break;
                    }
                }
            }
    
            //关闭窗体 
            private void close_Click(object sender, EventArgs e)
            {
                this.Close();
            }
    
            /// <summary>
            /// 提取像素法
            /// </summary>
            private void pixel_Click(object sender, EventArgs e)
            {
                //启动计时器
                myTimer.Start();
                if (curBitmpap != null)
                {
                    Color curColor;
                    int ret;
    
                    //二维图像数组循环
                    for(int i = 0; i < curBitmpap.Width; i++)
                    {
                        for(int j = 0; j < curBitmpap.Height; j++)
                        {
                            //获取该像素点的RGB颜色值
                            curColor = curBitmpap.GetPixel(i, j);
                            //利用公式计算灰度值
                            ret = (int)(curColor.R * 0.299 + curColor.G * 0.587 + curColor.B * 0.114);
                            //设置该像素点的灰度值,R=G=B=ret
                            curBitmpap.SetPixel(i, j, Color.FromArgb(ret, ret, ret));
                        }
                    }
                    //关闭计时器
                    myTimer.Stop();
                    //在TextBox内显示计时时间
                    timeBox.Text = myTimer.Duration.ToString("####.##") + "毫秒";
                    //对窗体进行重新绘制,这将强制执行Paint事件处理程序
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 内存法(适用于任意大小的24位彩色图像)
            /// </summary>
            private void memory_Click(object sender, EventArgs e)
            {
                //启动计时器
                myTimer.Start();
                if (curBitmpap != null)
                {
                    //位图矩形
                    Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height);
                    //以可读写的方式锁定全部位图像素
                    System.Drawing.Imaging.BitmapData bmpData = curBitmpap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmpap.PixelFormat);
                    //得到首地址
                    IntPtr ptr = bmpData.Scan0;
    
                    //定义被锁定的数组大小,由位图数据与未用空间组成的
                    int bytes = bmpData.Stride * bmpData.Height;
                    //定义位图数组
                    byte[] rgbValues = new byte[bytes];
                    //复制被锁定的位图像素值到该数组内
                    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
    
                    //灰度化
                    double colorTemp = 0;
                    for (int i = 0; i < bmpData.Height; i++)
                    {
                        //只处理每行中是图像像素的数据,舍弃未用空间
                        for (int j = 0; j < bmpData.Width * 3; j += 3)
                        {
                            //利用公式计算灰度值
                            colorTemp = rgbValues[i * bmpData.Stride + j + 2] * 0.299 + rgbValues[i * bmpData.Stride + j + 1] * 0.587 + rgbValues[i * bmpData.Stride + j] * 0.114;
                            //R=G=B
                            rgbValues[i * bmpData.Stride + j] = rgbValues[i * bmpData.Stride + j + 1] = rgbValues[i * bmpData.Stride + j + 2] = (byte)colorTemp;
                        }
                    }
    
                    //把数组复制回位图
                    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
                    //解锁位图像素
                    curBitmpap.UnlockBits(bmpData);
                    //关闭计时器
                    myTimer.Stop();
                    //在TextBox内显示计时时间
                    timeBox.Text = myTimer.Duration.ToString("####.##") + "毫秒";
                    //对窗体进行重新绘制,这将强制执行Paint事件处理程序
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 指针法
            /// </summary>
            private void pointer_Click(object sender, EventArgs e)
            {
                //启动计时器
                myTimer.Start();
                if (curBitmpap != null)
                {
                    //位图矩形
                    Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height);
                    //以可读写的方式锁定全部位图像素
                    System.Drawing.Imaging.BitmapData bmpData = curBitmpap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmpap.PixelFormat);
    
                    byte temp = 0;
                    //启用不安全模式
                    unsafe
                    {
                        //得到首地址
                        byte* ptr = (byte*)(bmpData.Scan0);
                        //二维图像循环
                        for (int i = 0; i < bmpData.Height; i++)
                        {
                            for (int j = 0; j < bmpData.Width; j++)
                            {
                                //利用公式计算灰度值
                                temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
                                //R=G=B
                                ptr[0] = ptr[1] = ptr[2] = temp;
                                //指向下一个像素
                                ptr += 3;
                            }
                            //指向下一行数组的首个字节
                            ptr += bmpData.Stride - bmpData.Width * 3;
                        }
                    }
                    //解锁位图像素
                    curBitmpap.UnlockBits(bmpData);
                    //关闭计时器
                    myTimer.Stop();
                    //在TextBox内显示计时时间
                    timeBox.Text = myTimer.Duration.ToString("####.##") + "毫秒";
                    //对窗体进行重新绘制,这将强制执行Paint事件处理程序
                    Invalidate();
                }
            }
    
            /// <summary>
            /// 内存法(仅适用于512*512的图像)
            /// </summary>
            //private void memory_Click(object sender, EventArgs e)
            //{
            //    if (curBitmpap != null)
            //    {
            //        //位图矩形
            //        Rectangle rect = new Rectangle(0, 0, curBitmpap.Width, curBitmpap.Height);
            //        //以可读写的方式锁定全部位图像素
            //        System.Drawing.Imaging.BitmapData bmpData = curBitmpap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmpap.PixelFormat);
            //        //得到首地址
            //        IntPtr ptr = bmpData.Scan0;
    
            //        //24位bmp位图字节数
            //        int bytes = curBitmpap.Width * curBitmpap.Height * 3;
            //        //定义位图数组
            //        byte[] rgbValues = new byte[bytes];
            //        //复制被锁定的位图像素值到该数组内
            //        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
    
            //        //灰度化
            //        double colorTemp = 0;
            //        for(int i = 0; i < rgbValues.Length; i += 3)
            //        {
            //            //利用公式计算灰度值
            //            colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
            //            //R=G=B
            //            rgbValues[i]=rgbValues[i+1]=rgbValues[i+2]=(byte)colorTemp;
            //        }
    
            //        //把数组复制回位图
            //        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
            //        //解锁位图像素
            //        curBitmpap.UnlockBits(bmpData);
            //        //对窗体进行重新绘制,这将强制执行Paint事件处理程序
            //        Invalidate();
            //    }
            //}
    
    
    
        }
    }

     

    /// <summary>
          /// 图像灰度化
          /// </summary>
          /// <param name="bmp"></param>
          /// <returns></returns>
          public static Bitmap ToGray(Bitmap bmp)
          {
              for (int i = 0; i < bmp.Width; i++)
              {
                  for (int j = 0; j < bmp.Height; j++)
                  {
                      //获取该点的像素的RGB的颜色
                      Color color = bmp.GetPixel(i, j);
                      //利用公式计算灰度值
                      int gray = (int)(color.R * 0.3 + color.G * 0.59 + color.B * 0.11);
                      Color newColor = Color.FromArgb(gray, gray, gray);
                      bmp.SetPixel(i, j, newColor);
                  }
              }
              return bmp;
          }

     

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Runtime.InteropServices;
    using System.ComponentModel;
    using System.Threading;
    
    namespace gray
    {
        internal class HiPerfTimer
        {
            //引用win32API中的QueryPerformanceCounter()方法
            //该方法用来查询任意时刻高精度计数器的实际值
            [DllImport("Kernel32.dll")]         //using System.Runtime.InteropServices;
            private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
    
            //引用win32API中的QueryPerformanceCounter()方法
            //该方法用来查询任意时刻高精度计数器的实际值
            [DllImport("Kernel32.dll")]
            private static extern bool QueryPerformanceFrequency(out long lpFrequency);
    
            private long startTime, stopTime;
            private long freq;
    
            public HiPerfTimer()
            {
                startTime = 0;
                stopTime = 0;
    
                if(QueryPerformanceFrequency(out freq) == false)
                {
                    //不支持高性能计时器
                    throw new Win32Exception();     //using System.ComponentModel;
                }
            }
    
            //开始计时
            public void Start()
            {
                //让等待线程工作
                Thread.Sleep(0);                //using System.Threading;
    
                QueryPerformanceCounter(out startTime);
            }
            //结束计时
            public void Stop()
            {
                QueryPerformanceCounter(out stopTime);
            }
            //返回计时结果(ms)
            public double Duration
            {
                get
                {
                    return (double)(stopTime - startTime) * 1000 / (double)freq;
                }
            }
    
        }
    }

     

    灰度图像二值化
    在进行了灰度化处理之后,图像中的每个象素只有一个值,那就是象素的灰度值。它的大小决定了象素的亮暗程度。为了更加便利的开展下面的图像处理操作,还需要对已经得到的灰度图像做一个二值化处理。图像的二值化就是把图像中的象素根据一定的标准分化成两种颜色。在系统中是根据象素的灰度值处理成黑白两种颜色。和灰度化相似的,图像的二值化也有很多成熟的算法。它可以采用自适应阀值法,也可以采用给定阀值法。

         #region Otsu阈值法二值化模块   
    
            /// <summary>   
            /// Otsu阈值   
            /// </summary>   
            /// <param name="b">位图流</param>   
            /// <returns></returns>   
            public Bitmap OtsuThreshold(Bitmap b)
            {
                // 图像灰度化   
                // b = Gray(b);   
                int width = b.Width;
                int height = b.Height;
                byte threshold = 0;
                int[] hist = new int[256];
    
                int AllPixelNumber = 0, PixelNumberSmall = 0, PixelNumberBig = 0;
    
                double MaxValue, AllSum = 0, SumSmall = 0, SumBig, ProbabilitySmall, ProbabilityBig, Probability;
                BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                unsafe
                {
                    byte* p = (byte*)data.Scan0;
                    int offset = data.Stride - width * 4;
                    for (int j = 0; j < height; j++)
                    {
                        for (int i = 0; i < width; i++)
                        {
                            hist[p[0]]++;
                            p += 4;
                        }
                        p += offset;
                    }
                    b.UnlockBits(data);
                }
                //计算灰度为I的像素出现的概率   
                for (int i = 0; i < 256; i++)
                {
                    AllSum += i * hist[i];     //   质量矩   
                    AllPixelNumber += hist[i];  //  质量       
                }
                MaxValue = -1.0;
                for (int i = 0; i < 256; i++)
                {
                    PixelNumberSmall += hist[i];
                    PixelNumberBig = AllPixelNumber - PixelNumberSmall;
                    if (PixelNumberBig == 0)
                    {
                        break;
                    }
    
                    SumSmall += i * hist[i];
                    SumBig = AllSum - SumSmall;
                    ProbabilitySmall = SumSmall / PixelNumberSmall;
                    ProbabilityBig = SumBig / PixelNumberBig;
                    Probability = PixelNumberSmall * ProbabilitySmall * ProbabilitySmall + PixelNumberBig * ProbabilityBig * ProbabilityBig;
                    if (Probability > MaxValue)
                    {
                        MaxValue = Probability;
                        threshold = (byte)i;
                    }
                }
                return this.Threshoding(b, threshold);
            } // end of OtsuThreshold 2  
            #endregion
    
            #region      固定阈值法二值化模块
            public Bitmap Threshoding(Bitmap b, byte threshold)
            {
                int width = b.Width;
                int height = b.Height;
                BitmapData data = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                unsafe
                {
                    byte* p = (byte*)data.Scan0;
                    int offset = data.Stride - width * 4;
                    byte R, G, B, gray;
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            R = p[2];
                            G = p[1];
                            B = p[0];
                            gray = (byte)((R * 19595 + G * 38469 + B * 7472) >> 16);
                            if (gray >= threshold)
                            {
                                p[0] = p[1] = p[2] = 255;
                            }
                            else
                            {
                                p[0] = p[1] = p[2] = 0;
                            }
                            p += 4;
                        }
                        p += offset;
                    }
                    b.UnlockBits(data);
                    return b;
    
                }
    
            }
            #endregion

     

    转载于:https://www.cnblogs.com/dearzhoubi/p/8571652.html

    展开全文
  • 灰度图像二值化方法的研究,基于MATLAB图像的处理
  • 这是一款实现图像灰度二值化处理功能源码,该源码主要是利用opencv2.framework进行图像灰度二值化处理,可以对图像的某个特定矩形区域进行二值化处理,效果如图所示,上方图片是原图,下方是对上方的图片的某个...
  • 在很多图像处理的过程中,经常需要对灰度图像进行二值化。本文对几种常用的图像二值化算法进行了阐述,并通过仿真,进行比较研究。根据实验结果,阐明了各种算法的优缺点。
  • 图像进行二值化处理,这里设定阈值为122,即最大灰度的一半
  • 这次简单的写了灰度图像二值化。。这是什么概念呢? 图像的二值化的基本原理 图像的二值化处理就是将图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。即将256个亮度等级的灰度图像通过适当的...

    前天闲着没事干,就写了写BMP图像处理,感觉大家还比较感兴趣。。所以现在没事,继续更新。。这次简单的写了灰度图像二值化。。这是什么概念呢?

    图像的二值化的基本原理

       图像的二值化处理就是将图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。

     

    相信大家看到这里应该觉得很简单吧。。二值化就是把原来灰度图像中每个像素的值要么变成255(白色),要么变为0(黑色)。(

    代码:

    #include<iostream>
    #include <Windows.h>
    
    using namespace std;
    
    
    void main()
    {
    	int threshold=200;
    	FILE* stream=fopen("D:\\6.bmp","rb");
    	if(stream==NULL)
    	{
    		cout<<"文件不存在"<<endl;
    		return;
    	}
    	
    	int sizeFileHeader=sizeof(BITMAPFILEHEADER);
    	int sizeInfoHeader=sizeof(BITMAPINFOHEADER);
    	
    	BITMAPFILEHEADER* bitmapFileHeader=new BITMAPFILEHEADER[sizeFileHeader+1];
    	
    	BITMAPINFOHEADER* bitmapInfoHeader=new BITMAPINFOHEADER[sizeInfoHeader+1];
    	
    	memset(bitmapFileHeader,0,sizeFileHeader+1);
    	memset(bitmapInfoHeader,0,sizeInfoHeader+1);
    	fread(bitmapFileHeader,sizeof(char),sizeFileHeader,stream);
    	fseek(stream,sizeFileHeader,0);
    	fread(bitmapInfoHeader,sizeof(char),sizeInfoHeader,stream);
    	fseek(stream,sizeInfoHeader+sizeFileHeader,0);
    	RGBQUAD* pRgbQuards=new RGBQUAD[256];
    	for (int k=0;k<256;k++)
    	{
    		fread(&pRgbQuards[k],sizeof(RGBQUAD),1,stream);
    	}
    	
    	int count=(((bitmapInfoHeader->biWidth)*8+31)/32)*4-bitmapInfoHeader->biWidth*(bitmapInfoHeader->biBitCount/8);
    	BYTE* tempData=new BYTE[count+1];
    	memset(tempData,0,count+1);
    	fseek(stream,sizeFileHeader+sizeInfoHeader+256*sizeof(RGBQUAD),0);
    	BYTE** data=new BYTE*[bitmapInfoHeader->biHeight];
    	for(int i=0;i<bitmapInfoHeader->biHeight;i++)
    	{
    		data[i]=new BYTE[bitmapInfoHeader->biWidth];
    		for (int j=0;j<bitmapInfoHeader->biWidth;j++)
    		{
    			fread(&data[i][j],sizeof(char),1,stream);
    			if(data[i][j]>threshold)
    				data[i][j]=255;
    			else
    				data[i][j]=0;
    		}
    		for (int n=0;n<count;n++)
    		{
    			fread(&tempData[n],sizeof(char),1,stream);
    		}
    	}
    	
    	fclose(stream);
    	
    
    
    	//写入。。
    	FILE* fileWrite=fopen("D:\\9.bmp","a+");
    	fwrite(bitmapFileHeader,sizeof(char),sizeof(BITMAPFILEHEADER),fileWrite);
    	fwrite(bitmapInfoHeader,sizeof(char),sizeof(BITMAPINFOHEADER),fileWrite);
    	fwrite(pRgbQuards,sizeof(RGBQUAD),256,fileWrite);
    
    	for(int i=0;i<bitmapInfoHeader->biHeight;i++)
    	{
    		for(int j=0;j<bitmapInfoHeader->biWidth;j++)
    		{
    			fwrite(&data[i][j],sizeof(BYTE),1,fileWrite);
    		}
    		for(int m=0;m<count;m++)
    			fwrite(&tempData[m],sizeof(char),1,fileWrite);
    	}
    	fclose(fileWrite);
    
    	cout<<"success"<<endl;
    }


    这里我就不解释了。看了前几篇文章肯定觉的very easy....

    效果:

    原图:

    二值图:

     

    MY QUESTION:上面说了二值化就是变成二值化图像,而我在网上查了资料说二值化图像像素的大小是1位,这就和上面说的不符合了,应该上面介绍的是还是8位。所以我就有些不懂了。。希望大神可以给我解释解释....

    转载于:https://www.cnblogs.com/james1207/p/3255894.html

    展开全文
  • 基于简单遗传算法的灰度图像二值化,采用的适应度函数为类间距最小、类内距最大,经过简单的修改可以处理任意格式的文件。
  • .NET Core 图像处理(图像二值化,图像灰度化,图像灰度反转) ImageSharp 是支持.NET Core跨平台图形处理库,本文将利用ImageSharp库实现图像二值化,图像灰度化,图像灰度反转。 图像二值化 public static ...
  • matlab灰度化、二值化处理图像

    万次阅读 多人点赞 2018-12-04 20:59:36
    matlab文字识别与提取: 1.图像转换为数字矩阵 ...rgb2gray :通过消除图像色调和饱和度信息同时保留亮度实现将将RGB图像或彩色图转换为灰度图像,即灰度化处理的功能 gdata = rgb2gray(data); ...
  • c#图像处理 图像预处理 灰度二值化 提取像素法 内存法 指针法 灰度化方法:最小值 最大值 加权平均法 二值化方法: 固定值 平均值 Bernsen算法
  • 主要介绍了Android实现图像灰度化、线性灰度变化和二值化处理方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • import cv2 from matplotlib import ...https://gxnotes.com/article/109552.html#Python在OpenCV中裁剪图像 https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_tutorials.html#doc
  • 灰度图像二值化

    2011-10-14 16:42:14
    介绍了图像及数字图像处理技术的一些概念和相关知识;对Matlab7.0 软 件的发展和软件在图像处理中的应用做了简要介绍;还介绍了灰度图像二值化方法以及利用Matlab7.0 软件工具进行算法的实现
  • 图像灰度化和二值化图像识别里面经常使用,这里以HLS实现整个过程 一、实现功能: 读取一张bmp图片,输出一张灰度化bmp图片和二值化后的黑白图片 二、需要用到的接口 1、读写图片工具函数bmp_tools.cpp 这里我们用...
  • 改程序是用C++中的opencv库完成的二值化灰度化的图像处理,功能很完善
  • 为了加快处理速度,在图像处理算法中,往往需要把彩色图像转换为灰度图像。 0x00. 灰度图 灰度数字图像是每个像素只有一个采样颜色的图像,这类图像通常显示为从最暗黑色到最亮的白色的灰度。 灰度图像与黑白图像...
  • 目录一、图像处理算法1、转化为灰度图像加权平均法(常用)平均法最大最小平均法2、灰度图像反转3、灰度图像二值化 一、图像处理算法 1、转化为灰度图像 加权平均法(常用) Image(x,y) = 0.3 * Image_R(x,y) +...
  • opencv图像处理灰度化和二值化

    千次阅读 2019-11-29 10:28:09
    本篇文章将通过灰度化和二值化&二值图像的腐蚀和膨胀的原理来介绍...1.1、图像二值化基本原理: 对灰度图像进行处理,设定阈值,在阈值中的像素值将变为1(白色部分),阈值为的将变为0(黑色部分)。 1.2、图...
  • RubyImageProcess(Ruby简单图像处理) 本项目使用Ruby解析Bmp文件,并实现简单的图片处理算法:二值化、浮雕、灰度化、底片等滤镜效果 原理介绍和效果预览请参考
  • Delphi图像处理灰度化、二值化、滤波,Delphi开发,简单实用
  • 实现了打开图像、保存图像、关闭以及通过提取像素法、内存法、指针法实现彩色图像灰度化
  • opencv图像处理初步(一):灰度化和二值化

    万次阅读 多人点赞 2018-08-07 16:36:54
    二、图像二值化处理步骤: (1)先对彩色图像进行灰度化 //img为原图,imgGray为灰度图 cvtColor(img, imgGray, CV_BGR2GRAY); (2)对灰度图进行二值化 //imgGray为灰度图,result为二值图像 /...
  • 这里主要实现的 opencv 基于 android 对图像进行常用处理,比如说灰度化,二值化,rgb的转换,这里就不贴主要代码,只是工具代码。Utils.xxx方法的使用需要在MainActivity.class中添加此方法(好像是掉用opencv,...

空空如也

空空如也

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

灰度图像二值化处理