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 訪問圖像像素
- 索引訪問
{
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);
}
- 通過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);
}
- 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>();
- 案例
{
//圖像減色算法
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) = af(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 圖像基本運算
- 圖像加法
// 兩圖片必須有相同的大小和位深度
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);
- 圖像加減
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);
- 圖像的乘除法
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);
- 圖像邏輯運算 按位操作
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);