C#,opencvsharp相关问题
c# videocapture不能读取视频的原因:
解决方案:缺少处理视频文件需要的dll,将opecv_ffmpeg.dll拷贝到dll文件中
自定义图片
string savePath = @"./img.jpg";
Scalar s = new Scalar(0, 0, 255);//创建一个颜色对象
/*
* 参数:
* 1: 行 --指定图像的像素行数,多个行组成图片的高度
* 2: 列 --指定图像的像素列数,多个列组成图片的宽度
* 3: 对象类型,结构体类型 矩阵数据类型(深度和通道数) MatType
* 4: 图像颜色
*/
Mat MyMat = new Mat(100, 100, MatType.CV_8UC4, s);//创建一个红色的图片
Window w = new Window("Mymat", WindowMode.Normal, MyMat);
Cv2.ImWrite(savePath, MyMat);
Cv2.WaitKey(0);
背景减法,转灰度图
Mat _PreMatdst = new Mat();
_PreMatdst = _PreMat.Clone();
int back_threshold = 10;
// 背景差分,absdiff,是相减后取绝对值
//Cv2.Absdiff(_PreMat, background, _PreMat);
// subtract
Cv2.Subtract(_PreMatdst, background, _PreMatdst);
// opencvsharp读取格式为bgr,转为灰度图
Cv2.CvtColor(_PreMatdst, _PreMatdst, ColorConversionCodes.BGR2GRAY);
c# opencvsharp获取背景图片
namespace background_model
{
class Program
{
static void Main()
{
string videoFile = @"D:\background_model\videos\video.mp4";
VideoCapture capture = new VideoCapture(videoFile);
if (!capture.IsOpened())
{
throw new InvalidOperationException("capture close");
}
BackgroundSubtractorMOG2 pBackSub = BackgroundSubtractorMOG2.Create();
Mat frame = new Mat();
Mat fgMask = new Mat();
int tmp = 0;
Mat total_img = new Mat();
int index_img = 0;
while (true)
{
capture.Read(frame);
if (frame.Empty())
break;
pBackSub.Apply(frame, fgMask);
Mat dst = new Mat(frame.Size(), MatType.CV_8UC3);
pBackSub.GetBackgroundImage(dst);
//Cv2.Rectangle(frame, new Point(10, 2), new Point(100, 20), Scalar.White, -1);
double ss = capture.Get(VideoCaptureProperties.PosFrames);
//Cv2.PutText(frame, ss.ToString(), new Point(15, 15), HersheyFonts.HersheySimplex, 0.5, Scalar.Black);
//Cv2.ImShow("Frame", frame);
//Cv2.ImShow("FG Mask", fgMask);
Cv2.ImShow("bg", dst);
int key = Cv2.WaitKey(30);
if (key == 'q' || key == 27)
break;
//tmp += 1;
//if (tmp > 100)
//{
// index_img += 1;
// total_img = total_img / (tmp - 1);
// total_img.ConvertTo(total_img, MatType.CV_8UC1);
// total_img.ImWrite("./back_imgs/" + index_img.ToString() + ".bmp");
// tmp = 1;
//}
//if (tmp == 1)
//{
// frame.ConvertTo(total_img, MatType.CV_32FC1);
//}
//else
//{
// frame.ConvertTo(frame, MatType.CV_32FC1);
// Cv2.Add(total_img, frame, total_img);
//}
}
}
}
}
Threshold
// ThresholdTypes.Binary:二值化,小于阈值的像素点置0,其它的置为255
// ThresholdTypes.BinaryInv:二值化,大于阈值的像素点置0,其它的置为255
// ThresholdTypes.Trunc:截断,大于阈值的像素点等于阈值,其它的不变
// ThresholdTypes.Tozero:小于阈值的像素点的值设定为0,其它的像素点保持不变
// ThresholdTypes.TozeroInv:大于阈值的像素点的值设定为0,其它的像素点保持不变
Cv2.Threshold(_PreMatdst, _PreMatdst, back_threshold, 255, ThresholdTypes.Binary);
滤波去噪
// 均值滤波去噪
Cv2.Blur(_PreMat, _PreMat, new OpenCvSharp.Size(5, 5));
// 中值滤波
Cv2.MedianBlur(_PreMatdst, _PreMatdst, 5);
// 高斯滤波, sigmaX, sigmaY为X和Y方向的标准偏差,仅指定了sigmaX,则sigmaY与sigmaX相同。如果两者都为零,则根据卷积核大小计算它们
Cv2.GaussianBlur(_PreMatdst, _PreMatdst, new OpenCvSharp.Size(5, 5), 0);
// 双边滤波
Cv2.BilateralFilter(_PreMat, _PreMatdst, 5, 10, 2);
腐蚀膨胀
//开运算
Cv2.Erode(_PreMat, _PreMat, element, new Point(-1, -1), 2);
Cv2.Dilate(_PreMat, _PreMat, element, new Point(-1, -1), 2);
找轮廓区域
OpenCvSharp.Point[][] contours;
HierarchyIndex[] hierarchy;
Cv2.FindContours(_PreMatdst, out contours, out hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxNone);
Point min_left_top = new Point(_PreMat.Width, _PreMat.Height);
Point max_right_down = new Point(0, 0);
for (int i = 0; i < contours.Length; i++)
{
double tmp_area = Cv2.ContourArea(contours[i]);
if (tmp_area > 500)
{
if_car = true;
Rect rec = Cv2.BoundingRect(contours[i]);
//_PreMatdst.DrawContours(contours, i, new Scalar(255, 0, 0), 3);
//Cv2.Rectangle(_PreMat, rec, new Scalar(0, 0, 255), 1);
//Cv2.PutText(_PreMat, (tmp_area).ToString(), new Point(rec.X, rec.Y), HersheyFonts.HersheyScriptSimplex, 1, new Scalar(0, 0, 255), 2);
}
}
k-means聚类
//k-means聚类
List<int[]> sample_list = new List<int[]>();
for (int w = 0; w < _PreMatdst.Width; w++)
{
for (int h = 0; h < _PreMatdst.Height; h++)
{
var tmp = _PreMatdst.At<Vec2b>(w, h);
if (tmp[0] == 255)
{
sample_list.Add(new int[] { w, h });
}
}
}
if (sample_list.Count > 0)
{
Mat samples = new Mat(sample_list.Count, 1, MatType.CV_32FC2);
for (int i = 0; i < sample_list.Count; i++)
{
samples.Set<Vec2f>(i, 0, new Vec2f(sample_list[i][0], sample_list[i][1]));
//samples.Set<int>(i, 1, sample_list[i][1]);
}
var bestLabels = new Mat();
var centers = new Mat();
Cv2.Kmeans(samples, 9, bestLabels, new TermCriteria(type: CriteriaTypes.Eps | CriteriaTypes.MaxIter, maxCount: 10, epsilon: 1.0), 5, KMeansFlags.PpCenters, centers);
for (int i = 0; i < 9; i++)
{
Point ipt = (Point)centers.At<Point2f>(i);
//Console.WriteLine(ipt);
Cv2.Circle(_PreMat, ipt.Y, ipt.X, 30, new Scalar(0, 255, 0), 1);
}
}