• #include using namespace std; #include "cv.h" #include "highgui.h" #pragma comment(lib,"cxcore.lib") #pragma comment(lib,"cv.lib") #pragma comment(lib,"ml.lib") ...#pragma comment(lib,"cv

    #include <iostream>
    using namespace std;

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

    #pragma  comment(lib,"cxcore.lib")
    #pragma  comment(lib,"cv.lib")
    #pragma  comment(lib,"ml.lib")
    #pragma  comment(lib,"cvaux.lib")
    #pragma  comment(lib,"highgui.lib")
    #pragma  comment(lib,"cvcam.lib")

    int main(int argc, char* argv[])
    {
        IplImage *img = cvLoadImage("101.jpg",1);
        CvScalar s;
     cvNamedWindow("Image",1);

     cvShowImage("Image",img);
        for(int i = 0;i < img->height;i++)
     {
            for(int j = 0;j < img->width;j++)
      {
       s = cvGet2D(img,i,j); // get the (i,j) pixel value
       s.val[0]=255;
       s.val[1]=34;
       s.val[2]=123; 
       cvSet2D(img,i,j,s);//set the (i,j) pixel value
            }
        }
        cvShowImage("Image",img);
        cvWaitKey(0); //等待按键
     
        cvDestroyWindow( "Image" );//销毁窗口
      //cvReleaseImage( &img ); //释放图像
     
        return 0;
    }

    上述的方法在效率方面不好,还有更快速的方法获取像素值:

    1. IplImage img;  
    2. for (i = 0;i < img->height;i++)  
    3. {  
    4.     for (j = 0;j < img->width;j++)  
    5.     {  
    6.         sum += ((uchar *)(img->imageData + img->widthStep * i))[j];//获取像素值  
    7.         num++;  
    8.     }  
    9. }  
    展开全文
  • Java OpenCV-4.0.0 图像处理8 图像像素点的获取与操作 java OpenCV-4.0.0 获取图像像素点并对像素点进行操作 /** * OpenCV-4.0.0 获取图像像素点 */ public static void getPixelImage() { Mat src = Imgcodecs....

    Java OpenCV-4.0.0 图像处理8 图像像素点的获取与操作

    java OpenCV-4.0.0 获取图像像素点并对像素点进行操作

    package com.xu.image;
    
    import org.opencv.core.Core;
    import org.opencv.core.Mat;
    import org.opencv.core.Size;
    import org.opencv.highgui.HighGui;
    import org.opencv.imgcodecs.Imgcodecs;
    import org.opencv.imgproc.Imgproc;
    
    /**  
     * 
     * @Title: OpenCV.java   
     * @Package com.xu.opencv   
     * @Description: TODO   
     * @author: xuhyacinth     
     * @date: 2019年1月17日 下午7:54:15   
     * @version V-1.0 
     * @Copyright: 2019 xuhyacinth
     *
     */
    public class Test {
    
    	static {
    		//在使用OpenCV前必须加载Core.NATIVE_LIBRARY_NAME类,否则会报错
    		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    	}
    
    	public static void main(String[] args) {
    		getPixelImage();
    	}
    
    	/**
    	 * OpenCV-4.0.0 获取图像像素点
    	 * @return: void  
    	 * @date: 2019年1月17日 下午8:24:07
    	 */
    	public static void getPixelImage_1() {
    		Mat src = Imgcodecs.imread("C:\\Users\\Administrator\\Pictures\\0001.jpg");
    		Mat dst = new Mat(src.size(),src.type());
    
    		int channels = src.channels();//获取图像通道数
    		double[] pixel = new double[3];//用于存放像素点
    
    		for (int i = 0, rlen = src.rows(); i < rlen; i++) {
    			for (int j = 0, clen = src.cols(); j < clen; j++) {
    				if (channels == 3) {//图片为3通道即平常的(B,G,R)
    					pixel = src.get(i, j).clone();
    					pixel[0] = 255 - pixel[0];//B
    					pixel[1] = 255 - pixel[1];//G
    					pixel[2] = 255 - pixel[2];//R
    					dst.put(i, j, pixel);
    				} else {//图片为单通道
    					dst.put(i, j, src.get(i, j).clone());
    				}
    			}
    		}
    		Imgproc.resize(src, src, new Size(src.cols()/2,src.rows()/2));
    		HighGui.imshow("图片测试", dst);
    		HighGui.waitKey(0);
    	}
    
    	/**
    	 * OpenCV-4.0.0 获取图像像素点
    	 * @return: void  
    	 * @date: 2019年11月24日 下午8:24:07
    	 */
    	public static void getPixelImage_2() {
    		Mat src = Imgcodecs.imread("C:\\Users\\Administrator\\Pictures\\0001.jpg");
    		
    		Mat dst = new Mat(src.size(),src.type());
    		double[] pixel = new double[3];//用于存放像素点
    
    		for (int i = 0 ,row = (int) src.size().height; i < row; i++) {
    			for (int j = 0,col = (int) src.size().width; j < col; j++) {
    				pixel = src.get(i, j).clone();
    				pixel[0] = 255 - pixel[0];//B
    				pixel[1] = 255 - pixel[1];//G
    				pixel[2] = 255 - pixel[2];//R
    				dst.put(i, j, pixel);
    			}
    		}
    		HighGui.imshow("图片测试", dst);
    		HighGui.waitKey(0);
    	}
    
    }
    
    
    

    1

    展开全文
  • c#图像处理入门 -bitmap类和图像像素获取方法  转自 一.Bitmap类 Bitmap对象封装了GDI+的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的...

    c#图像处理入门

    -bitmap类和图像像素值获取方法

     转自http://blog.csdn.net/jiangxinyu/article/details/6222302

    一.Bitmap类

    Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下:

    1. GetPixel方法和SetPixel方法:获取和设置一个图像的指定像素的颜色.

    2. PixelFormat属性:返回图像的像素格式.

    3. Palette属性:获取和设置图像所使用的颜色调色板.

    4. Height Width属性:返回图像的高度和宽度.

    5. LockBits方法和UnlockBits方法:分别锁定和解锁系统内存中的位图像素.在基于像素点的图像处理方法中使用LockBits和UnlockBits是一个很好的方式,这两种方法可以使我们指定像素的范围来控制位图的任意一部分,从而消除了通过循环对位图的像素逐个进行处理,每调用LockBits之后都应该调用一次UnlockBits.

    二.BitmapData类

    BitmapData对象指定了位图的属性

    1. Height属性:被锁定位图的高度.

    2. Width属性:被锁定位图的高度.

    3. PixelFormat属性:数据的实际像素格式.

    4. Scan0属性:被锁定数组的首字节地址,如果整个图像被锁定,则是图像的第一个字节地址.

    5. Stride属性:步幅,也称为扫描宽度.

     

     

    如上图所示,数组的长度并不一定等于图像像素数组的长度,还有一部分未用区域,这涉及到位图的数据结构,系统要保证每行的字节数必须为4的倍数.

    三.Graphics类

    Graphics对象是GDI+的关键所在,许多对象都是由Graphics类表示的,该类定义了绘制和填充图形对象的方法和属性,一个应用程序只要需要进行绘制或着色,它就必须使用Graphics对象.

    四.Image类

      这个类提供了位图和元文件操作的函数.Image类被声明为abstract,也就是说Image类不能实例化对象,而只能做为一个基类

    1.FromFile方法:它根据输入的文件名产生一个Image对象,它有两种函数形式:

    public static Image FromFile(string filename);

    public static Image FromFile(string filename, bool useEmbeddedColorManagement);

    2.FromHBitmap方法:它从一个windows句柄处创建一个bitmap对象,它也包括两种函数形式:

    public static bitmap fromhbitmap(intptr hbitmap);

    public static bitmap fromhbitmap(intptr hbitmap, intptr hpalette);

    3. FromStream方法:从一个数据流中创建一个image对象,它包含三种函数形式:

    public static image fromstream(stream stream);

    public static image fromstream(stream stream, bool useembeddedcolormanagement);

    fromstream(stream stream, bool useembeddedcolormanagement, bool validateimagedata);

     

    有了上面的了解,我们便可以开始利用C#做图像处理,下面介绍几种方法:

    一.   打开、保存、显示图像

            privateBitmap srcBitmap = null;

              privateBitmap showBitmap = null;

            //打开文件

            privatevoid menuFileOpen_Click(object sender, EventArgs e)

            {

                OpenFileDialog openFileDialog = newOpenFileDialog();

                openFileDialog.Filter = @"Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg";

                openFileDialog.FilterIndex = 3;

                openFileDialog.RestoreDirectory = true;

                if (DialogResult.OK == openFileDialog.ShowDialog())

                {

                    srcBitmap = (Bitmap)Bitmap.FromFile(openFileDialog.FileName, false);

                    showBitmap = srcBitmap;

                    this.AutoScroll = true;

                    this.AutoScrollMinSize =

    newSize((int)(showBitmap.Width), (int)(showBitmap.Height));

                    this.Invalidate();

                 }

            }

            //保存图像文件

            privatevoid menuFileSave_Click(object sender, EventArgs e)

            {

                if (showBitmap != null)

                {

                    SaveFileDialog saveFileDialog = newSaveFileDialog();

                    saveFileDialog.Filter =

    @"Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg";

                    saveFileDialog.FilterIndex = 3;

                    saveFileDialog.RestoreDirectory = true;

                    if (DialogResult.OK == saveFileDialog.ShowDialog())

                    {   

                        ImageFormat format = ImageFormat.Jpeg;

                        switch (Path.GetExtension(saveFileDialog.FileName).ToLower())

                        {

                            case".jpg":

                                format = ImageFormat.Jpeg;

                                break;

                            case".bmp":

                                format = ImageFormat.Bmp;

                                break;

                            default:

                                MessageBox.Show(this, "Unsupported image format was specified", "Error",

                                    MessageBoxButtons.OK, MessageBoxIcon.Error);

                                return;

                        }

                        try

                        {

                            showBitmap.Save(saveFileDialog.FileName,format );

                        }

                        catch (Exception)

                        {

                            MessageBox.Show(this, "Failed writing image file", "Error",

                                MessageBoxButtons.OK, MessageBoxIcon.Error);

                        }

                    }

                }

            }

     

    c#中将bitmap或者image保存为清晰的gif

    在c#中默认可以讲bitmap保存为gif等格式,但是这种保存方法保存的gif会严重失真,正常情况下的代码:

    1 System.Drawing.Bitmap b = new System.Drawing.Bitmap(“c://original_image.gif“); 
    2   System.Drawing.Image thmbnail = b.GetThumbnailImage(100,75,null,new IntPtr()); 

    3   thmbnail.Save(“c://thumnail.gif“, System.Drawing.Imaging.ImageFormat.Gif); 

    一个批量处理图片的软件,包括各种处理方式,处理效果,但是在保存为gif的时候出现了问题,在网上查了很久也没有发现一个可用的改善gif图片质量的方法,找到了一个解决办法,保存出来的gif容量大减,但是效果基本符合常规这中方法就是就是“Octree“ 算法。

    “Octree“ 算法允许我们插入自己的算法来量子化我们的图像。

     

    一个好的“颜色量子化”算法应该考虑在两个像素颗粒之间填充与这两个像素颜色相近的过渡颜色,提供更多可视颜色空间。

     

    Morgan Skinner提供了很好的“Octree“ 算法代码,大家可以下载参考使用。

     

      使用OctreeQuantizer很方便:

     System.Drawing.Bitmap b = new System.Drawing.Bitmap(“c://original_image.gif“);

     System.Drawing.Image thmbnail = b.GetThumbnailImage(100,75,null,new IntPtr());

     OctreeQuantizer quantizer = new OctreeQuantizer ( 255 , 8 ) ;

     using ( Bitmap quantized = quantizer.Quantize ( thmbnail ) )

     {

       quantized.Save(“c://thumnail.gif“, System.Drawing.Imaging.ImageFormat.Gif);

     }

     OctreeQuantizer grayquantizer = new GrayscaleQuantizer ( ) ;

     using ( Bitmap quantized = grayquantizer.Quantize ( thmbnail ) )

     {

       quantized.Save(“c://thumnail.gif“, System.Drawing.Imaging.ImageFormat.Gif);

    }

    你可以点击这里下载类的文件(项目文件),根据我的试用,只需要两个类文件(OctreeQuantizer.cs,Quantizer.cs)即可运行,将这两个类文件的namespace改成你项目的名称就行,还有,需要在不安全编译的方式下编译,右击项目名称,在生成选项卡里选择"允许不安全代码"即可

     

     

        //窗口重绘,在窗体上显示图像,重载Paint

            privatevoid frmMain_Paint(object sender, System.Windows.Forms.PaintEventArgs e)

            {

                if (showBitmap != null)

                {

                    Graphics g = e.Graphics;

                    g.DrawImage(showBitmap, newRectangle(this.AutoScrollPosition.X, this.AutoScrollPosition.Y ,

                    (int)(showBitmap.Width), (int)(showBitmap.Height)));

                }

            }

             //灰度化

            privatevoid menu2Gray_Click(object sender, EventArgs e)

            {

                if (showBitmap == null) return;

                showBitmap = RGB2Gray(showBitmap);//下面都以RGB2Gray为例

                this.Invalidate();

            }

    二.   提取像素法

          这种方法简单易懂,但相当耗时,完全不可取.

    publicstaticBitmap RGB2Gray(Bitmap srcBitmap)

            {

                Color srcColor;

                int wide = srcBitmap.Width;

                int height = srcBitmap.Height;

                for (int y = 0; y < height; y++)

                    for (int x = 0; x < wide; x++)

                    {

                        //获取像素的RGB颜色值

                        srcColor = srcBitmap.GetPixel(x, y);

                        byte temp = (byte)(srcColor.R * .299 + srcColor.G * .587 + srcColor.B * .114);

                        //设置像素的RGB颜色值

                        srcBitmap.SetPixel(x, y, Color.FromArgb(temp, temp, temp));

                    }

                return srcBitmap ;

            }

    三.   内存法

    这是比较常用的方法

    publicstaticBitmap RGB2Gray(Bitmap srcBitmap)

            {

                int wide = srcBitmap.Width;

                int height = srcBitmap.Height;

                Rectangle rect = newRectangle(0, 0, wide, height);

                //将Bitmap锁定到系统内存中,获得BitmapData

                BitmapData srcBmData = srcBitmap.LockBits(rect,

                          ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                //创建Bitmap

                 Bitmap dstBitmap = CreateGrayscaleImage(wide, height);//这个函数在后面有定义

                BitmapData dstBmData = dstBitmap.LockBits(rect,

                          ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

                //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行

                System.IntPtr srcPtr = srcBmData.Scan0;

                System.IntPtr dstPtr = dstBmData.Scan0;

                //将Bitmap对象的信息存放到byte数组中

                int src_bytes = srcBmData.Stride * height;

                byte[] srcValues = newbyte[src_bytes];

                int dst_bytes = dstBmData.Stride * height;

                byte[] dstValues = newbyte[dst_bytes];

                //复制GRB信息到byte数组

                System.Runtime.InteropServices.Marshal.Copy(srcPtr, srcValues, 0, src_bytes);

                System.Runtime.InteropServices.Marshal.Copy(dstPtr, dstValues, 0, dst_bytes);

                //根据Y=0.299*R+0.114*G+0.587B,Y为亮度

                for (int i = 0; i < height; i++)

                    for (int j = 0; j < wide; j++)

                    {

                      //只处理每行中图像像素数据,舍弃未用空间

                      //注意位图结构中RGB按BGR的顺序存储

                        int k = 3 * j;

                        byte temp = (byte)(srcValues[i * srcBmData.Stride + k + 2] * .299

                             + srcValues[i * srcBmData.Stride + k + 1] * .587

    + srcValues[i * srcBmData.Stride + k] * .114);

                        dstValues[i * dstBmData.Stride + j] = temp;

                    }

                System.Runtime.InteropServices.Marshal.Copy(dstValues, 0, dstPtr, dst_bytes);

                //解锁位图

                srcBitmap.UnlockBits(srcBmData);

                dstBitmap.UnlockBits(dstBmData);

                return dstBitmap; 

            } 

    四  指针法

    C/C++的习惯,不是C#的特点

    publicstaticBitmap RGB2Gray(Bitmap srcBitmap)

            {

                int wide = srcBitmap.Width;

                int height = srcBitmap.Height ;

                Rectangle rect = newRectangle(0, 0, wide, height);

                BitmapData srcBmData = srcBitmap.LockBits(rect,

                          ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                Bitmap dstBitmap = CreateGrayscaleImage(wide, height);

                BitmapData dstBmData = dstBitmap.LockBits(rect,

                          ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);   

                System.IntPtr srcScan = srcBmData.Scan0;

                System.IntPtr dstScan = dstBmData.Scan0;

                Unsafe //启动不安全代码

                {

                    byte* srcP = (byte*)(void*) srcScan;

                    byte* dstP = (byte*)(void*) dstScan;

                    int srcOffset = srcBmData.Stride - wide * 3;

                    int dstOffset = dstBmData.Stride - wide ;

                    byte red, green, blue;

                    for (int y = 0; y < height; y++)

                    {

                        for (int x = 0; x <wide ; x++, srcP += 3, dstP++)

                        {

                            blue = srcP [0];

                            green = srcP [1];

                            red = srcP [2];

                            * dstP = (byte)(.299 * red + .587 * green + .114 * blue);

                           

                        }

                        srcP += srcOffset;

                        dstP += dstOffset;

                    }

                }

                srcBitmap.UnlockBits(srcBmData);

                dstBitmap.UnlockBits(dstBmData );

                return dstBitmap; 

            }

    五.   矩阵法

    并不是什么新方法,只是将图像数据分做R,G,B三个矩阵(二维数组)存储,类似MATLAB的习惯.

           publicstaticbool GetRGB(Bitmap Source, outint[,] R, outint[,] G, outint[,] B)

            {

                try

                {

                    int iWidth = Source.Width;

                    int iHeight = Source.Height; 

                    Rectangle rect = newRectangle(0, 0, iWidth, iHeight);

                    System.Drawing.Imaging.BitmapData bmpData = Source.LockBits(rect,

    System.Drawing.Imaging.ImageLockMode.ReadWrite, Source.PixelFormat);

                    IntPtr iPtr = bmpData.Scan0; 

                    int iBytes = iWidth * iHeight * 3;

                    byte[] PixelValues = new byte[iBytes];

                    System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);

                    Source.UnlockBits(bmpData); 

                    R = newint[iHeight, iWidth];

                    G = newint[iHeight, iWidth];

                    B = newint[iHeight, iWidth]; 

                    int iPoint = 0; 

                    for (int i = 0; i < iHeight; i++)

                    {

                        for (int j = 0; j < iWidth; j++)

                        {

                            B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);

                            G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);

                            R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);

                        }

                    } 

                    return true;

                }

                catch (Exception)

                {

                    R = null;

                    G = null;

                    B = null; 

                    returnfalse;

                }

            }

            publicstaticBitmap FromRGB(int[,] R, int[,] G, int[,] B)

            {

                int iWidth = G.GetLength(1);

                int iHeight = G.GetLength(0);

                Bitmap Result = newBitmap(iWidth, iHeight,

    System.Drawing.Imaging.PixelFormat.Format24bppRgb); 

                Rectangle rect = newRectangle(0, 0, iWidth, iHeight);

                System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect,

    System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                IntPtr iPtr = bmpData.Scan0;

                int iStride = bmpData.Stride;

                int iBytes = iWidth * iHeight * 3;

                byte[] PixelValues = newbyte[iBytes];

                int iPoint = 0; 

                for (int i = 0; i < iHeight; i++)

                    for (int j = 0; j < iWidth; j++)

                    {

                        int iG = G[i, j];

                        int iB = B[i, j];

                        int iR = R[i, j];

                        PixelValues[iPoint] = Convert.ToByte(iB);

                        PixelValues[iPoint + 1] = Convert.ToByte(iG);

                        PixelValues[iPoint + 2] = Convert.ToByte(iR);

                        iPoint += 3;

                    }

                 System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes);

                 Result.UnlockBits(bmpData);

                 return Result;

            }

            publicstaticbool GetGray(Bitmap srcBitmap, outbyte [,] gray)

            { 

                Bitmap tempBitmap;

                if (srcBitmap.PixelFormat != PixelFormat.Format8bppIndexed)

                    tempBitmap = ImageProcess.Image.Gray(srcBitmap);

                else

                    tempBitmap = srcBitmap;

     

                int wide = tempBitmap.Width;

                int height = tempBitmap.Height;

                gray = newbyte [height, wide];

                BitmapData gbmData = tempBitmap.LockBits(newRectangle(0, 0, wide, height),

                      ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

                System.IntPtr ScanG = gbmData.Scan0;

                int gOffset = gbmData.Stride - wide;

                unsafe

                {

                    byte* g = (byte*)(void*)ScanG;

                    for (int y = 0; y < height; y++)

                    {

                        for (int x = 0; x < wide; x++, g++)

                        {

                            gray[y ,x ] =*g;

                        }

                        g += gOffset;

                    }

                }

                 tempBitmap.UnlockBits(gbmData);

                returntrue ;

             }

            Public static Bitmap FromGray(byte [,] Gray)

            {

                int iWidth = Gray.GetLength(1);

                int iHeight = Gray.GetLength(0);

                Bitmap dstBitmap = ImageProcess.Image.CreateGrayscaleImage(iWidth, iHeight);

                BitmapData gbmData = dstBitmap.LockBits(newRectangle(0, 0, iWidth, iHeight),

                          ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

                System.IntPtr ScanG = gbmData.Scan0;

                int gOffset = gbmData.Stride - iWidth;

                unsafe

                {

                    byte* g = (byte*)(void*)ScanG; 

                    for (int i = 0; i < iHeight; i++)

                    {

                        for (int j = 0; j < iWidth; j++)

                        {

                            *g=(byte )Gray[i, j] ;

                            g++;

                        }

                        g += gOffset;

                    }

                } 

                dstBitmap.UnlockBits(gbmData); 

                return dstBitmap;

            }

             ///<summary>

             /// Create and initialize grayscale image

             ///</summary>

             publicstaticBitmap CreateGrayscaleImage( int width, int height )

             {

                  // create new image

                  Bitmap bmp = newBitmap( width, height, PixelFormat.Format8bppIndexed );

                  // set palette to grayscale

                  SetGrayscalePalette( bmp );

                  // return new image

                  return bmp;

             }//#

             ///<summary>

             /// Set pallete of the image to grayscale

             ///</summary>

             publicstaticvoid SetGrayscalePalette( Bitmap srcImg )

             {

                  // check pixel format

                  if ( srcImg.PixelFormat != PixelFormat.Format8bppIndexed )

                       thrownewArgumentException( );

                  // get palette

                  ColorPalette cp = srcImg.Palette;

                  // init palette

                  for ( int i = 0; i < 256; i++){

                       cp.Entries[i] = Color.FromArgb( i, i, i );

                  }

                  srcImg.Palette = cp;

             }

     

    C#数字图像处理的3种典型方法(精简版)

     

    C#数字图像处理有3种典型方法:提取像素法、内存法、指针法。其中提取像素法使用的是GDI+中的Bitmap.GetPixel和Bitmap.SetPixel方法;内存法是通过LockBits方法来获取位图的首地址,从而把图像数据直接复制到内存中进行处理;指针法与内存法相似,但该方法直接应用指针对位图进行操作,由于在默认情况下,C#不支持指针运算,所以该方法只能在unsafe关键字所标记的代码块中使用。以一幅真彩色图像的灰度化为例,下面代码分别展现了这3种方法的使用,方便大家学习图像处理的基本技巧。

    (1) 像素提取法

    if (curBitmap != null)

    {

          Color curColor;

          int gray;

          for (int i = 0; i < curBitmap.Width; i++)

          {

                 for (int j = 0; j < curBitmap.Height; j++)

                 {

                        curColor = curBitmap.GetPixel(i, j);

                        gray = (int)(0.3 * curColor.R + 0.59 * curColor.G * 0.11 * curColor.B);

                        curBitmap.SetPixel(i, j, curColor);

                 }

          }

    }

    (2) 内存法

    if (curBitmap != null)

    {

          int width = curBitmap.Width;

          int height = curBitmap.Height;

          int length = height * 3 * width;

          RGB = new byte[length];

         BitmapData data = curBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

          System.IntPtr Scan0 = data.Scan0;

          System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length);

          double gray = 0;

          for (int i = 0; i < RGB.Length; i=i+3)

          {

                 gray = RGB[i + 2] * 0.3 + RGB[i + 1] * 0.59 + RGB[i] * 0.11;

                 RGB[i + 2] = RGB[i + 1] = RGB[i] = (byte)gray;

          }

          System.Runtime.InteropServices.Marshal.Copy(RGB, 0, Scan0, length);

          curBitmap.UnlockBits(data);

    }

    (3) 指针法

    if (curBitmap != null)

    {

          int width = curBitmap.Width;

          int height = curBitmap.Height;

         BitmapData data = curBitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

          System.IntPtr Scan0 = data.Scan0;

          int stride = data.Stride;

          System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length);

          unsafe

          {

                 byte* p = (byte*)Scan0;

                 int offset = stride - width * 3;

                 double gray = 0;

                 for (int y = 0; y < height; y++)

                 {

                        for (int x = 0; x < width; x++)

                        {

                               gray = 0.3 * p[2] + 0.59 * p[1] + 0.11 * p[0];

                               p[2] = p[1] = p[0] = (byte)gray;

                               p += 3;

                        }

                        p += offset;

                 }

          }

          curBitmap.UnlockBits(data);

             }

    在以上3种方法中,提取像素法能直观的展示图像处理过程,可读性很好,但效率最低,并不适合做图像处理方面的工程应用;内存法把图像直接复制到内存中,直接对内存中的数据进行处理,速度明显提高,程序难度也不大;指针法直接应用指针来对图像进行处理,所以速度最快。

     

     

    简单图片处理函数代码(C#

     

    一、生成图片并实现颜色渐变效果 
        Response.Clear(); 
        Bitmap imgOutput = new Bitmap(100, 50); 
        Graphics gic = Graphics.FromImage(imgOutput);

    gic.Clear(Color.BlueViolet); 
        gic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
        gic.DrawString("渐变图形", new Font("黑体",16,FontStyle.Italic),

    new SolidBrush(Color.White),new PointF(2,2)); 
        gic.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0,0),

    new Point(100,50), Color.FromArgb(0,0,0,0),

    Color.FromArgb(255,255,255,255)),0,0,100,50);

        imgOutput.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Jpeg); 
        gic.Dispose(); 
        imgOutput.Dispose(); 
        Response.End(); 

    二、对图片进行反转 
        System.Drawing.Image drawimage = System.Drawing.Image.FromFile(photopath);//photopath表示图片的物理地址 
        drawimage.RotateFlip(RotateFlipType.Rotate270FlipNone); 
        if(File.Exists(photopath)) 
        { 
             File.SetAttributes(photopath,FileAttributes.Normal); 
             File.Delete(photopath); 
        } 
        drawimage.Save(photopath,System.Drawing.Imaging.ImageFormat.Jpeg); 
        drawimage.Dispose(); 

    三、对图片进行缩放 
        System.Drawing.Image drawimage = System.Drawing.Image.FromFile(photopath); 
        Bitmap imgOutput = new Bitmap(drawimage,60,30); 
        imgOutput.Save(newphotppath, System.Drawing.Imaging.ImageFormat.Jpeg); 
        imgOutput.Dispose();   
        Response.End(); 

    其他还有一些画线、画矩形、画圆等的函数和方法都可以在System.Drawing中找到;

    本文的实例是一个数字图像处理的应用程序,它完成的功能包括对图像颜色的翻转、对图像进行灰度处理和对图像进行增亮处理。该程序对图像进行处理部分的代码包含在一个专门的Filters类里面,通过调用该类里的静态成员函数,我们就可以实现相应的图像处理功能了。为实现图像处理,我们要对图像进行逐个象素处理。我们知道图像是由一个个的象素点组成的,对一幅图像的每个象素进行了相应的处理,最后整个图像也就处理好了。在这个过程中,我们只需对每个象素点进行相应的处理,在处理过程中却不需要考虑周围象素点对其的影响,所以相对来说程序的实现就变得简单多了。

      由于GDI+中的BitmapData类不提供对图像内部数据的直接访问的方法,我们唯一的办法就是使用指针来获得图像的内部数据,这时我们就得运用unsafe这个关键字来指明函数中访问图像内部数据的代码块了。在程序中,我还运用了打开文件和保存文件等选项,以使我们的辛勤劳动不付之东流。

      二.程序的实现:

      

    Invert()、Gray()、Brightness()等三个函数均包含在Filters类里面,

    Invert()函数的算法如下:

    public static bool Invert(Bitmap b)

     {

     BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),

        ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

     int stride = bmData.Stride;

     System.IntPtr Scan0 = bmData.Scan0;

     unsafe

     {

      byte * p = (byte *)(void *)Scan0;

      int nOffset = stride - b.Width*3;

      int nWidth = b.Width * 3;

      for(int y=0;y<b.Height;++y)

      {

       for(int x=0; x < nWidth; ++x )

       {

        p[0] = (byte)(255-p[0]);

        ++p;

       }

       p += nOffset;

      }

     }

     b.UnlockBits(bmData);

     return true;

     }

    该函数以及后面的函数的参数都是Bitmap类型的,它们传值的对象就是程序中所打开的图像文件了。该函数中的BitmapData类型的bmData包含了图像文件的内部信息,bmData的Stride属性指明了一条线的宽度,而它的Scan0属性则是指向图像内部信息的指针。本函数完成的功能是图像颜色的翻转,实现的方法即用255减去图像中的每个象素点的值,并将所得值设置为原象素点处的值,对每个象素点进行如此的操作,只到整幅图像都处理完毕。函数中的unsafe代码块是整个函数的主体部分,首先我们取得图像内部数据的指针,然后设置好偏移量,同时设置nWidth为b.Width*3,因为每个象素点包含了三种颜色成分,对每个象素点进行处理时便要进行三次处理。接下来运用两个嵌套的for循环完成对每个象素点的处理,处理的核心便是一句:p[0] = (byte)(255-p[0]);。在unsafe代码块后,便可运用b.UnlockBits(bmData)进行图像资源的释放。函数执行成功,最后返回true值。注:由于是要编译不安全代码,所以得将项目属性页中的"允许不安全代码块"属性设置为true,

     

    Gray()函数的算法如下:

    public static bool Gray(Bitmap b)

     {

            BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height),

                      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

     int stride = bmData.Stride;

     System.IntPtr Scan0 = bmData.Scan0;

     unsafe

     {

      byte * p = (byte *)(void *)Scan0;

      int nOffset = stride - b.Width*3;

      byte red, green, blue;

      for(int y=0;y<b.Height;++y)

     {

        for(int x=0; x < b.Width; ++x )

      {

       blue = p[0];

       green = p[1];

       red = p[2];

       p[0] = p[1] = p[2] = (byte)(.299 * red + .587 * green + .114 * blue);

       p += 3;

      }

      p += nOffset;

     }

     }

     b.UnlockBits(bmData);

     return true;

     }

      本函数完成的功能是对图像进行灰度处理,我们的基本想法可是将每个象素点的三种颜色成分的值取平均值。然而由于人眼的敏感性,这样完全取平均值的做法的效果并不好,所以在程序中我取了三个效果最好的参数:.299,.587,.114。不过在这里要向读者指明的是,在GDI+中图像存储的格式是BGR而非RGB,即其顺序为:Blue、Green、Red。所以在for循环内部一定要设置好red、green、blue等变量的值,切不可颠倒。函数执行成功后,同样返回true值。

     

    Brightness()函数的算法如下:

    public static bool Brightness(Bitmap b, int nBrightness)

     {

      if (nBrightness < -255 || nBrightness > 255)

       return false;

      BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width,

                                        b.Height), ImageLockMode.ReadWrite,

                                        PixelFormat.Format24bppRgb);

      int stride = bmData.Stride;

      System.IntPtr Scan0 = bmData.Scan0;

      int nVal = 0;

      unsafe

      {

       byte * p = (byte *)(void *)Scan0;

       int nOffset = stride - b.Width*3;

       int nWidth = b.Width * 3;

       for(int y=0;y<b.Height;++y)

       {

          for(int x=0; x < nWidth; ++x )

           {

        nVal = (int) (p[0] + nBrightness);

        if (nVal < 0) nVal = 0;

        if (nVal > 255) nVal = 255;

        p[0] = (byte)nVal;

        ++p;

            }

           p += nOffset;

       }

      }

      b.UnlockBits(bmData);

      return true;

     }

      本函数完成的功能是对图像进行增亮处理,它比上面两个函数多了一个增亮参数-nBrightness,该参数由用户输入,范围为-255~255。在取得了增亮参数后,函数的unsafe代码部分对每个象素点的不同颜色成分进行逐个处理,即在原来值的基础上加上一个增亮参数以获得新的值。同时代码中还有一个防止成分值越界的操作,因为RGB成分值的范围为0~255,一旦超过了这个范围就要重新设置。函数最后执行成功后,同样得返回true值。

      该函数实现的程序效果如下:

     

      首先,我们把图像增亮的参数设置为100(其范围为-255~255),然后执行效果如下,读者也可尝试其他的参数值。

     

      三.小结:

      本文通过一个简单的实例向大家展现了用Visual C#以及GDI+完成数字图像处理的基本方法,通过实例,我们不难发现合理运用新技术不仅可以大大简化我们的编程工作,还可以提高编程的效率。不过我们在运用新技术的同时也得明白掌握基本的编程思想才是最主要的,不同的语言、不同的机制只是实现的具体方式不同而已,其内在的思想还是相通的。对于上面的例子,掌握了编写图像处理函数的算法,用其他的方式实现也应该是可行的。同时,在上面的基础上,读者不妨试着举一反三,编写出更多的图像处理的函数来,以充实并完善这个简单的实例。

    image与byte数组的转换

    image to byte[]

      MemoryStream ms=new MemoryStream();
       byte[] imagedata=null;
       pictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Gif );
       imagedata=ms.GetBuffer ();

    byte[] to image

      ms = New IO.MemoryStream(by)
      img = Drawing.Image.FromStream(ms)
    展开全文
  • 从前面的文字就可以看出,对数字图像处理都是在像素级上操作的,准确地讲是操作像素点的RGB值,在图像取反和灰度图像转换两篇已经涉及到了对RGB操作的相关代码,相信大家已经也看到了,就是这一段:for (int j...

    从前面的文字中就可以看出,对数字图像的处理都是在像素级上操作的,准确地讲是操作像素点的RGB值,在图像取反灰度图像转换两篇中已经涉及到了对RGB操作的相关代码,相信大家已经也看到了,就是这一段:

    for (int j = 0; j < height; j++) {
        for (int i = 0; i < width; i++) {
            int p = image.getRGB(i, j);
    
            int a = (p >> 24) & 0xff;
            int r = (p >> 16) & 0xff;
            int g = (p >> 8) & 0xff;
            int b = p & 0xff;
    
            p = (a << 24) | (r << 16) | (g << 8) | b;
    
            image.setRGB(i, j, p);
        }
    }

    其中这里的变量r,g,b就是对应的rgb值,那为什么要这样操作呢?先看一个图:


    这里写图片描述

    有了这个图相信大家就都看明白了,首先p是一个32位的二进制数,可以通过getRGB()方法得到,那么最前面的8位是alpha,后面依次是Red,Green,Blue。所以这就是代码中移位操作的意义,当然最后还要回归到原来的结构,那就用(a << 24) | (r << 16) | (g << 8) | b再拼装一次。

    所以对图像中像素点的操作就可以这么写啦,后面具体是增强还是锐化,都是基于这样的操作做的。

    展开全文
  • 1、获取图像像素指针 1.获取图像像素指针是什么? 2.相应API 3.获取目的 2、像素范围处理saturate_cast 1.像素范围处理是什么? 2.像素范围处理API 3、掩膜操作 1.掩膜是什么? 2.掩膜操作是什么? 3.掩膜...

    目录

    一、前言

    二、图像像素基本操作

    1、获取图像像素指针

    1.获取图像像素指针是什么?

    2.相应API

    3.获取目的

    2、像素范围处理saturate_cast

    1.像素范围处理是什么?

    2.像素范围处理API

    3、掩膜操作

    1.掩膜是什么?

    2.掩膜操作是什么?

    3.掩膜操作的作用?

    4.API

    三、全部代码及结果展示

    1、代码

    2、运行效果图


    一、前言

    欠下的总是要还的,继续给大家更新有关于OpenCV的教程,很久没给大家更新,希望能得到大家的谅解。

    今天要讲的是图像像素比较简单的几个基本操作,包括图像矩阵的掩膜操作,获取像素的指针、图像像素范围处理以filter2D的介绍。

    图像处理很大程度上是对像素的处理,通过对比像素,修改像素,可以实现降噪、平滑、检测等功能。

    二、图像像素基本操作

    1、获取图像像素指针

    1.获取图像像素指针是什么?

    二维图像保存在电脑中,大家可以理解为矩阵,一个二维数组,每个位置都会有一个像素值。

    访问像素值,就是访问二维数组中某个位置的值。

    2.相应API

    访问的时候,我们先访问行,后访问列,通过如下方式,我们获取行指针,索引i表示第几行,从0开始计行数。

    Mat.ptr<uchar>(int i=0) //获取像素矩阵的指针,索引i表示第几行,从0开始计行数。

    我们通过行指针,可以获取到该行的的所有点,即所有像素。

    const uchar*  current= myImage.ptr<uchar>(row); //获得当前行指针
    
    p(row, col) =current[col]  //获取当前像素点P(row, col)的像素值。
    
    

    3.获取目的

    获取到像素点,我们就可以对这个像素点进行操作,如果我们加上循环嵌套,还可以遍历所有的像素点,即对所有的像素点进行操作。

    2、像素范围处理saturate_cast<uchar>

    1.像素范围处理是什么?

    我们在设置图像像素的灰度值或者RGB值时候,如果不了解,会随意设置,以RGB为例,他们的取值范围是从0 到255,所以如果我们输入范围以外的数据,为防止程序出错,我们需要控制范围,保证我们输入非法数据时候,不会导致程序出现问题。

    处理的原则如下:

    如果我们输入小于0的值,它会返回0,

    如果我们输入大于255的值,它会返回255,

    如果我们输入0-255之间的值,它会正常返回

    2.像素范围处理API

    像素范围处理的API是saturate_cast<uchar>:

    saturate_cast<uchar>(-100) //返回 0
    saturate_cast<uchar>(288)  //返回255
    saturate_cast<uchar>(100)  //返回100

    3、掩膜操作

    1.掩膜是什么?

    在讲掩膜操作之前,先给大家说一下什么是掩膜。

    我们不考虑别的地方什么是掩膜,我也不会给大家讲掩膜的标准定义,我们既然说图像的掩膜操作,那么我们就说在图像掩膜操作中的这个掩膜到底是什么。

    这个掩膜就是一个n*n的矩阵。通过掩膜去遍历图像,

    图像与掩膜

    2.掩膜操作是什么?

    接下来我们讲掩膜操作,我们用数字模拟一个图像,左边是一个10*10的图像矩阵,右边是一个掩膜,他们两个做操作。

    首先,左边黄色的3*3方块与掩膜对应位置相乘,求得的值,存放在新图像上的对应于原图上的中心位置的中间的位置。就像下图一样:

    下图的操作是:

    5 * 0 + 5 * (-1) + 5 * 0 + 5 * (-1) + 5 * 5 + 5 * (-1) + 5 * 0 + 5 * (-1) + 5 * 0 = 5

    掩膜操作

    由于图像所有都是5,所以上面这个经过掩膜操作并没有什么太明显的变化。

    全部做掩膜操作

    做完掩膜操作,边上的像素是做不到的,对于不同的算法,边上的像素做法不同,在这里先不说,以后会给大家详细讲解。

    我们再看一个示例:

    全部做掩膜操作

    对于外层一圈,不同算法不同,有的算法是将最外层全部设为0,有的是设为与其距离最近的像素点一致,有的是在原图外层加一层,这样经过掩膜的图像就是与原图一样尺寸了。

    3.掩膜操作的作用?

    掩膜操作实现图像对比度调整

    4.API

    掩膜操作的API是filter2D,函数原型是:

    void filter2D( 
        InputArray src, 
        OutputArray dst, 
        int ddepth,                            
        InputArray kernel, 
        Point anchor = Point(-1,-1),                            
        double delta = 0, 
        int borderType = BORDER_DEFAULT 
    );

    函数参数含义如下:

    (1)InputArray类型的src ,输入图像。

    (2)OutputArray类型的dst ,输出图像,图像的大小、通道数和输入图像相同。

    (3)int类型的ddepth,目标图像的所需深度。

    (4)InputArray类型的kernel,卷积核(或者更确切地说是相关核)是一种单通道浮点矩阵;如果要将不同的核应用于不同的通道,请使用split将图像分割成不同的颜色平面,并分别对其进行处理。。

    (5)Point类型的anchor,表示锚点(即被平滑的那个点),注意他有默认值Point(-1,-1)。如果这个点坐标是负值的话,就表示取核的中心为锚点,所以默认值Point(-1,-1)表示这个锚点在核的中心。。

    (6)double类型的delta,在将筛选的像素存储到dst中之前添加到这些像素的可选值。说的有点专业了其实就是给所选的像素值添加一个值delta。

    (7)int类型的borderType,用于推断图像外部像素的某种边界模式。有默认值BORDER_DEFAULT。

    如下面这个例子:

    filter2D( src, dst, src.depth(), kernel );

     

    三、全部代码及结果展示

    1、代码

    #include <opencv2/opencv.hpp>
    #include <iostream>
    #include <math.h>
    
    using namespace cv;
    
    int main(int argc, char** argv) {
    	Mat src, dst;
    	src = imread("D:/hand.png");
    	if (!src.data) {
    		printf("could not load image...\n");
    		return -1;
    	}
    	
    	
    	/*
    	int cols = (src.cols-1) * src.channels();
    	int offsetx = src.channels();
    	int rows = src.rows;
    
    	dst = Mat::zeros(src.size(), src.type());
    	for (int row = 1; row < (rows - 1); row++) {
    		const uchar* previous = src.ptr<uchar>(row - 1);
    		const uchar* current = src.ptr<uchar>(row);
    		const uchar* next = src.ptr<uchar>(row + 1);
    		uchar* output = dst.ptr<uchar>(row);
    		for (int col = offsetx; col < cols; col++) {
    			output[col] = saturate_cast<uchar>(5 * current[col] - (current[col- offsetx] + current[col+ offsetx] + previous[col] + next[col]));
    		}
    	}
    	*/
    	double t = getTickCount();
    	Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    	filter2D(src, dst, src.depth(), kernel);
    	double timeconsume = (getTickCount() - t) / getTickFrequency();
    	printf("tim consume %.2f\n", timeconsume);
    
    
    	imshow("input image", src);
    	imshow("contrast image demo", dst);
    
    	waitKey(0);
    	return 0;
    }

    2、运行效果图

    原图

     

    掩膜操作后的图像

    今天的内容就讲到这里啦,有什么问题,大家可以在下面留言哦!

    展开全文
  • 一直想自己写一个图像处理的软件。在网络上找各种图像处理方面的技术文章。但是找到的往往不是高深的理论,就是用C++等语言写出来的例程,非常不便。其实很多时候,我想找的只是一种描述,或者是伪代码,既有利于...
  • 像素一词是个外来词,在英文像素这个单词Pixels就是由“Picture(图像)”和“Element(元素)”两个单词的词头“Pi-el-”拼合而成的。是构成图像的元素的意思。从中文来说,像素这个术语是“图像元素”一词的...
  • 原理:图像数字化是将一幅画面转化成计算机能处理的形式——数字图像的过程。 将一幅图像分割成如图的一个个小区域(像元或像素),并将各小区域灰度用整数表示,形成一幅点阵式的数字图像。 包括采样和量化两个...
  • Python像素图像处理

    2019-05-24 09:20:55
    仅仅为了简单地熟悉像素处理方法 做的是14年的建模A题嫦娥登陆。 其中一个问题是这样的 如何选择下面这个图(月球表面高度2400米处的照片)的嫦娥三号着陆点? 其实官方给的数据里有图像中每个点...
  • 数字图像处理数字图像处理 一学习内容总结 第一章 绪论 1 什么是数字图像处理 2 使用数字图像处理领域的实例 3 数字图像处理的基本步骤 4 图像处理系统的组成 第二章 数字图像处理基础 1 视觉感知要素 2 光和电磁...
  • 1、impixel 获取图像像素值 作用获取图像像素值,函数返回指定图像的虹路蓝值。 p=impixel(I) 用鼠标在图像上选取所点击图像处的像素值 p=impixel(I,c,r); c r表示指定位置的索取像素的位置 I=imread('lena....
  • 图像像素值的访问与修改是最常用的一种操作。VTK提供了两种访问图像像素值的访问。 一、直接访问  第一种方法是直接发访问vtkImageData的数据数组。vtkImageData提供了GetScalarPointer()函数获取数据数组指针...
  • 《访问图像中每个像素的值》,这是之前写的了,用的也是2.0的风格IplImage*格式,不太适用后来Mat的格式,特此重写一篇。 以下例子源自《The OpenCV Tutorials --Release 2.4.2》2.2 How to scan images, lookup ...
  • !!此篇是基于IplImage* (C接口或者说2.1之前版本的接口,新的Mat的访问方式请参考...《访问Mat图像中每个像素的值》) IplImage是OpenCVCxCore部分基础的数据结构,用来表示图像,其中Ipl是Intel Image P
  • 在阅读图像处理方面的论文时,面对梯度、散度、黑塞矩阵、傅里叶变换等这些本该在微积分早已耳熟能详的概念时,很多人仍然感觉一筹莫展。为了弭平图像处理道路上的数学险阻,帮助更多人学好数字图像处理,并更快地...
  • 该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。...
  • 本篇文章讲解图像灰度化处理的知识,结合OpenCV调用cv2.cvtColor()函数实现图像灰度操作,使用像素处理方法对图像进行灰度化处理。基础性知识希望对您有所帮助。 1.图像灰度化原理 2.基于OpenCV的图像灰度化处理 3....
  • 本文主要通过彩色图象灰度化来介绍C#处理数字图像的3种方法,Bitmap类、BitmapData类和Graphics类是C#处理图像的的3个重要的类。 Bitmap只要用于处理像素数据定义的图像的对象,主要方法和属性如下:  ...
  • 转自:c#图像处理入门 -bitmap类和图像像素获取方法   一.Bitmap类 Bitmap对象封装了GDI+的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要...
  • 像素值的读写 很多时候,我们需要读取某个像素值,或者设置...函数 at()来实现读去矩阵的某个像素,或者对某个像素进行赋值操作。 下面两行代码演示了 at()函数的使用方法。uchar value = grayim.at(i,j);//读出第 i
1 2 3 4 5 ... 20
收藏数 68,872
精华内容 27,548