C#程序版本
如果喜欢请点个关注哦!
本教程是根据B站同名的一个3h快速入门C++课程改写(https://www.bilibili.com/video/BV16K411W7x9),在这里使用了C#语言重新实现。
在本篇教程中我们将学会基础的一些OpenCV操作。同时在这篇教程中也会告诉你为什么有时候内存会突突突的往上狂涨。
建议您配合上面视频和官方API文档食用。
点击标题栏上面的“项目”,然后点击“管理Nuget包”。现在搜索“OpenCvSharp4”点击安装。安装完毕后,还需要安装一个运行环境,继续搜索“OpenCvSharp4.RunTime”选择您的系统配置。
当您全部配置好后,您可以引用包using OpenCvSharp;
(名字可能不对qwq)
下面是对照视频的C#程序改写版本。
string path = @"Resources\Course\test.png";
Mat img = Cv2.ImRead(path);
Cv2.ImShow("Pic", img);
Cv2.WaitKey(0);
其中Mat的意思是它为一个矩阵,我们在图像之中看到的是一个个的像素点。具体请参考B站视频。
注意,当您使用了ImShow的时候,记得要使用WaitKey。原因请看官方文档。
理解Mat结构,请您在这里稍微停顿,翻翻资料。
string path = @"Resources\Course\test_video.mp4";
VideoCapture cap = new VideoCapture(path);
Mat img = new Mat();
while (true) {
cap.Read(img);
if (!img.Empty()) {
Cv2.ImShow("Video", img);
} else {
Console.WriteLine("ERROR|NO IMG");
break;
}
Cv2.WaitKey(1);
Thread.Sleep(30);
}
通过VideoCapture类实例化了cap,这个cap具有读写视频的能力,其后原理是一帧帧的读入,然后显示。
当然,您可以可以直接开启本地摄像头。
VideoCapture cap = new VideoCapture(2);
如果摄像头打不开,记得使用DSHOW的API,作为参数2的值。(请直接用VS2019帮你补全代码吧)
Mat img = new Mat(512, 512, MatType.CV_8UC3);
其中8是8bit图 U是无符号 C是color通道数为3
具体涵义请见官方文档。或见这篇博客:https://blog.csdn.net/liuweiyuxiang/article/details/76929534
注意,OpenCV的Scalar用的是BGR通道。Blue Green Red。
Cv2.Circle(img, new OpenCvSharp.Point(256, 256), 155, new Scalar(0, 69, 255),5);
Cv2.Circle(img, new OpenCvSharp.Point(256, 256), 155, new Scalar(0, 69, 255), -1);//当为负数的时候,进行花园,C++用FILLED进行代替
Cv2.Rectangle(img, new OpenCvSharp.Point(130, 226), new OpenCvSharp.Point(382, 286), new Scalar(255, 255, 255), 3);
Cv2.Line(img, new OpenCvSharp.Point(130, 226), new OpenCvSharp.Point(382, 296), new Scalar(255, 255, 255), 3);
Cv2.PutText(img, "A Bad Apple!", new OpenCvSharp.Point(137, 262), HersheyFonts.HersheyDuplex, 0.75, new Scalar(255, 20, 245));
注意,绘制中文字体需要使用GDI+接口,通过GDI操作BitMap来绘制,这又是另一件事情了,暂时不在这里讨论。
waitKey()函数的功能是不断刷新图像,频率时间为delay,单位为ms
返回值为当前键盘按键值。
Cv2.CvtColor(img, imgGray, ColorConversionCodes.BGR2GRAY);
//BGE To(2) Gray
Cv2.GaussianBlur(img, imgGauss, new OpenCvSharp.Size(7, 7), 5, 0);
具体参数请看官方文档。
Cv2.Canny(imgGauss, imgCandy, 50, 150);
OpenCv已经帮助我们封装好了这些算法,可以说相当的方便,具体底层算法需要花点功夫好好的了解一下。
意思就好像这个字体变得膨胀变得消瘦。
//定义一个自定义膨胀的内核
Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));//这里只能使用奇数
//核心实现函数(这个是膨胀)
Cv2.Dilate(imgCandy, imgDia, kernel);
//腐蚀的实现函数
Cv2.Erode(imgCandy, imgDia, kernel);
Cv2.Resize(img, imgResize, new OpenCvSharp.Size(600, 200));//重新印刷大小
Cv2.Resize(img, imgResize, new OpenCvSharp.Size(), 0.5f, 0.5f);//在x,y轴
imgCrop = img[new OpenCvSharp.Rect(100, 100, 300, 250)];//这里和python语法一样
内存蹭蹭的往上涨:
官方OpenCvSharp在Github上的建议是:
使用using(){}
来托管代码,这样当不被占用的时候就会手动释放。
感谢您阅读,接下来小熊将会抽空编写这个系列的“下”篇。
敬请关注哦~