当前位置: 首页 > 工具软件 > Emgu CV > 使用案例 >

EmguCV基本操作(一)

毋修为
2023-12-01

1 EmguCV

1.1 访问图片

 //默认彩色模式打开
            Mat srcImg = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\22.jpg", LoadImageType.Color);

            if (srcImg.IsEmpty)
            {
                Console.WriteLine("文件图片找不到");
                return;
            }

            Console.WriteLine($"图像宽度为:{srcImg.Cols}");//获取图片的列
            Console.WriteLine($"图像高度为:{srcImg.Rows}");//获取图片的行
            Console.WriteLine($"图像通道数为:{srcImg.NumberOfChannels}");//获取图片通道数

            CvInvoke.NamedWindow("srcImg window", NamedWindowType.AutoSize);

            CvInvoke.Imshow("srcImg window", srcImg);

            CvInvoke.CvtColor(srcImg, srcImg, ColorConversion.Bgr2Gray);//转化为灰度图像

            CvInvoke.Imshow("outImg window", srcImg);
            CvInvoke.WaitKey(0);
            CvInvoke.DestroyWindow("srcImg window");//销毁指定窗口
            CvInvoke.DestroyAllWindows();//销毁所有窗口

2 点、矩形框

Point pt = new Point(100, 100);
            pt.X = 10;
            pt.Y = 20;

            Rectangle rect = new Rectangle();
            rect.X = 10;
            rect.Y = 20;
            rect.Width = 100;
            rect.Height = 200;
            bool bFlg = rect.Contains(new Point(0,0));//判断点是否在矩形框内
            Size size = rect.Size;

            //MCvScalar mCvScalar = new MCvScalar();
            Mat img = new Mat(500,500,DepthType.Cv8U,3);
            img.SetTo(new MCvScalar(0, 0, 0));

            CvInvoke.Line(img, new Point(10, 10), new Point(250, 250), new MCvScalar(0, 255, 0),2,LineType.EightConnected);
            CvInvoke.Circle(img, new Point(250, 250), 100, new MCvScalar(0, 0, 255), 2);
            CvInvoke.Circle(img, new Point(350, 350), 100, new MCvScalar(0, 0, 255), -1);

            CvInvoke.Rectangle(img, new Rectangle(100, 100, 300, 200), new MCvScalar(255, 0, 0), 2);
            CvInvoke.Rectangle(img, new Rectangle(50, 50, 300, 200), new MCvScalar(255, 0, 0), -1);

            //椭圆
            CvInvoke.Ellipse(img, new RotatedRect(new PointF(100, 110), new SizeF(300, 200),0),new MCvScalar(0,255,255),2,LineType.FourConnected);
            CvInvoke.Ellipse(img, new Point(250, 250), new Size(150, 100), 0, 0, 360, new MCvScalar(0, 0, 255), 2);

            CvInvoke.PutText(img, "hello world", new Point(100, 100), FontFace.HersheyComplex, 2, new MCvScalar(255, 255, 0), 5);

            CvInvoke.Imshow("--->", img);
            CvInvoke.WaitKey(0);

3 访问图像像素

  1. 索引访问
{
    Console.WriteLine("通过索引访问像素值");
    Image<Bgr, Byte> img = new Image<Bgr, byte>(@"C:\Users\Administrator\Desktop\22.jpg");
    for (int i = 0; i < img.Rows; i++)
    {
        for (int j = 0; j < img.Cols; j++)
        {
            if (i==j)
            {
                img[i,j] = new Bgr(0, 0, 255);//把第i行,第j列设置成红色
            }
        }
    }
    CvInvoke.Imshow("Image",img);
    CvInvoke.WaitKey(0);
} 

  1. 通过Data访问
{
    Console.WriteLine("通过Data索引访问,速度比较快  返回TDepth类型");
    //单通道灰度图像像素访问
    Image<Bgr, Byte> img = new Image<Bgr, byte>(@"C:\Users\Administrator\Desktop\22.jpg");
    for (int i = 0; i < img.Rows; i++)
    {
        for (int j = 0; j < img.Cols; j++)
        {
            if (i == j)
            {
                img.Data[i, j, 0] = 0;//像素值改变赋值(第100行100列 0通道)蓝
                img.Data[i, j, 1] = 255;//像素值改变赋值(第100行100列 0通道)//绿
                img.Data[i, j, 2] = 0;//像素值改变赋值(第100行100列 0通道)//红
                //img[i, j] = new Bgr(0, 0, 255);//把第i行,第j列设置成红色
            }
        }
    }

    CvInvoke.Imshow("Image", img);
    CvInvoke.WaitKey(0);
} 

  1. Image类与Mat类的转化
Console.WriteLine("Image类与Mat类的转换");
//Image类转Mat
Image<Bgr, Byte> img = new Image<Bgr, byte>(@"C:\Users\Administrator\Desktop\22.jpg");
Mat matResult = img.Mat;

//Mat转Image类
Mat img2 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\22.jpg", LoadImageType.Color);
Image<Bgr, Byte> result = img2.ToImage<Bgr, Byte>();

  1. 案例
{
	//图像减色算法
	Console.WriteLine("图像减色算法");
	Image<Bgr, Byte> img = new Image<Bgr, Byte>(@"C:\Users\Administrator\Desktop\22.jpg");
	byte reduceValue = 64;//减色系数
	for (int i = 0; i < img.Rows; i++)
	{
	    for (int j = 0; j < img.Cols; j++)
	    {
	        img.Data[i, j, 0] = (byte)((byte)(byte)((byte)(img.Data[i, j, 0] / reduceValue) * reduceValue)  + (byte)(reduceValue / 2));
	        img.Data[i, j, 1] = (byte)((byte)(byte)((byte)(img.Data[i, j, 1] / reduceValue) * reduceValue)  + (byte)(reduceValue / 2));
	        img.Data[i, j, 2] = (byte)((byte)(byte)((byte)(img.Data[i, j, 2] / reduceValue) * reduceValue)  + (byte)(reduceValue / 2));
	    }
	}
	CvInvoke.Imshow("img", img);
	CvInvoke.WaitKey(0);
}


{
	//模拟雪花或者椒盐噪声
	Console.WriteLine("模拟雪花或者椒盐噪声");
    Image<Bgr, Byte> img = new Image<Bgr, Byte>(@"C:\Users\Administrator\Desktop\22.jpg");
      int snowNum = 5000;//椒盐噪声的数量
      Random random = new Random();
      for (int k = 0; k < snowNum; k++)
      {
          int i = random.Next() % img.Rows;
          int j = random.Next() % img.Cols;
          img.Data[i, j, 0] = 255;
          img.Data[i, j, 1] = 255;
          img.Data[i, j, 2] = 255;
      }
      CvInvoke.Imshow("img", img);
      CvInvoke.WaitKey(0);
}

4 对比度亮度调整

4.1 原理

对比度亮度调整:
原理: g(x) = af(x)+b
1、参数 f(x)表示原图像像素
2、参数 g(x)表示输出图像像素
3、参数 a(a>0),被称之为增益(Gain),通常用来控制图像对比度
4、参数 b通常称之为偏置(bias),通常用来控制图像的亮度
g(i,j) = a
f(i,j)+b

  Image<Bgr, Byte> img = new Image<Bgr, byte>(@"C:\Users\Administrator\Desktop\22.jpg");
  Image<Bgr, Byte> img2 = img.Clone();//创建img副本

  int contrast = 100;//对比度
  Byte brightness = 16;//亮度

  for (int i = 0; i < img.Rows; i++)
  {
      for (int j = 0; j < img.Cols; j++)
      {
          int color_B = (int)((0.01 * contrast) * img.Data[i, j, 0] + brightness);
          int color_G = (int)((0.01 * contrast) * img.Data[i, j, 1] + brightness);
          int color_R = (int)((0.01 * contrast) * img.Data[i, j, 2] + brightness);
          if (color_B>255)
          {
              color_B = 255;
          }
          if (color_G > 255)
          {
              color_G = 255;
          }
          if (color_R > 255)
          {
              color_R = 255;
          }

          if (color_B < 0)
          {
              color_B = 0;
          }
          if (color_G < 0)
          {
              color_G = 0;
          }
          if (color_R < 0)
          {
              color_R = 0;
          }
          img.Data[i, j, 0] = (Byte)color_B;
          img.Data[i, j, 1] = (Byte)color_G;
          img.Data[i, j, 2] = (Byte)color_R;
      }
  }
  CvInvoke.Imshow("img show", img);
  CvInvoke.WaitKey(0);

5 图像通道分离与合并

Mat img3 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\22.jpg", LoadImageType.Color);
  Mat[] channelsArray = img3.Split();
   CvInvoke.Imshow("B", channelsArray[0]);
   CvInvoke.Imshow("G", channelsArray[1]);
   CvInvoke.Imshow("R", channelsArray[2]);

   //通道合并
   Mat dst = new Mat();
   VectorOfMat vectorOfMat =  new VectorOfMat();
   for (int i = 0; i < 3; i++)
   {
       CvInvoke.Threshold(channelsArray[i], channelsArray[i], 100, 255, ThresholdType.Binary);

       vectorOfMat.Push(channelsArray[i]);
   }
   CvInvoke.Merge(vectorOfMat, dst);
   CvInvoke.Imshow("img vectorOfMat", dst);
   CvInvoke.Imshow("img show", img3);
   CvInvoke.WaitKey(0);

6 图像基本运算

  1. 图像加法
// 两图片必须有相同的大小和位深度
	Mat img1 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\22.jpg", LoadImageType.Color);
	Mat img2 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\11.png", LoadImageType.Color);
	Mat dstImg = new Mat();
	CvInvoke.Add(img1, img2, dstImg);
	//按照权重叠加
	CvInvoke.AddWeighted(img1, 0.5, img2, 0.5, 0, dstImg);
  1. 图像加减
	Mat img1 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\22.jpg", LoadImageType.Color);
	Mat img2 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\11.PNG", LoadImageType.Color);
	Mat dstImg = new Mat();
	
	//CvInvoke.Subtract(img1, img2, dstImg);//差值   小于0 取0
	CvInvoke.AbsDiff(img1, img2, dstImg);//差值的绝对值
	CvInvoke.Imshow("result Img", dstImg);
	CvInvoke.WaitKey(0);
  1. 图像的乘除法
	Mat img1 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\22.jpg", LoadImageType.Color);
	Mat img2 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\11.PNG", LoadImageType.Color);
	
	Mat temp = new Mat(new Size(img1.Cols,img1.Rows),DepthType.Cv8U,3);
	temp.SetTo(new MCvScalar(1,5,1));
	Mat dstImg = new Mat();
	CvInvoke.Multiply(img1, temp, dstImg, 1);//矩阵相乘
	
	//CvInvoke.Divide(img1, temp, dstImg, 1);//矩阵相除
	CvInvoke.Imshow("result Img", dstImg);
	CvInvoke.WaitKey(0);
  1. 图像逻辑运算 按位操作
Mat img1 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\111.png", LoadImageType.Color);
Mat img2 = CvInvoke.Imread(@"C:\Users\Administrator\Desktop\222.png", LoadImageType.Color);
Mat dstImg = new Mat();
//CvInvoke.BitwiseAnd(img1, img2, dstImg);//图像相与
//CvInvoke.BitwiseOr(img1, img2, dstImg);//图像相或
//CvInvoke.BitwiseNot(img1,dstImg);//逻辑非
CvInvoke.BitwiseXor(img1, img2, dstImg);//图像异或
CvInvoke.Imshow("result Img", dstImg);
CvInvoke.WaitKey(0);

 类似资料: