前奏就是我太懒了
来个前奏,我T——M——D有点太懒了 去年9月开的专栏 今年9月都还没写 damn!不过还是在当一个合格的打工人,吃着猪食当着牛马。
我准备用我正在做的项目 简单写一写opencv 图像部分,最后会完成并给出一个完整的项目代码!给自己记录,也帮帮小白,希望不会误导小白。大佬直接掉头上秋名山,或者指点一二。
图像是什么?
图像就是一个对象。对象是什么?反正我没有
opencvsharp里图像的对象就是Mat,Mat的公开属性和方法去看官网hh
定义流程接口
这个接口你看着办,不想要就不要,反正不要钱。后期不再重复赘述
public class ProcessingResult
{
public Mat Image { get; set; }
public Size ImageSize { get; set; }
public Point[][] Contours { get; set; }
public ProcessingResult()
{
Contours = new Point[0][];
Image = new Mat();
}
public ProcessingResult(Mat mat)
{
Contours = new Point[0][];
Image = mat;
}
public ProcessingResult(Point[][] contours,Size size)
{
Contours = contours;
Image = new Mat();
ImageSize = size;
}
public ProcessingResult(Point[][] contours, Mat mat)
{
Contours = contours;
Image = mat;
}
}
public enum ImageProcessingStepType
{
Image, Contours,
Preprocessing
}
public interface IImageProcessingStep
{
ImageProcessingStepType StepType { get; }
string Name { get; }
ProcessingResult ProcessImage(Mat src, Dictionary<string, object> parameters);
}
颜色空间
颜色空间的组合有非常多种。此示例只是罗列几种常用的。
public class ColorSpaceStep : IImageProcessingStep
{
public ImageProcessingStepType StepType => ImageProcessingStepType.Image;
public static IList<string> sColorModes = new[] { "Gray", "BGR", "HSV", "HLS" };
public string Name => "颜色空间";
public ProcessingResult ProcessImage(Mat src, Dictionary<string, object> parameters)
{
var modeobj = parameters.GetValueOrDefault("Mode", 0).ToString();
var channelobj = parameters.GetValueOrDefault("Channel", -1).ToString();
var isIntobj = parameters.GetValueOrDefault("IsInv", false).ToString();
if (bool.TryParse(isIntobj, out bool IsInv)&& IsInv)
{
Mat dst = new Mat();
Cv2.BitwiseNot(src, dst);
return new(dst);
}
else if (int.TryParse(modeobj, out int colorModeInd) && int.TryParse(channelobj, out int channel))
{
if (!src.Channels().Equals(1))
{
Mat dst = new Mat();
dst = colorModeInd switch
{
0 => src.CvtColor(ColorConversionCodes.BGR2GRAY),
1 => channel.Equals(0) ? src : src.Split()[channel - 1],
2 => channel.Equals(0) ? src : src.CvtColor(ColorConversionCodes.BGR2HSV).Split()[channel - 1],
3 => channel.Equals(0) ? src : src.CvtColor(ColorConversionCodes.BGR2HLS).Split()[channel - 1],
_ => src.Clone()
};
return new(dst);
}
}
return new(src);
}
}
但是说实话,我也用到很少这类的通道提取的方法,更多的是src.CvtColor(ColorConversionCodes.BGR2GRAY)
这个方法的使用。ColorConversionCodes里面有非常多的转换。你需要找到你对应需要的转换类型。我列举几个常用的转换
//BGR和Gray的互相转换
src.CvtColor(ColorConversionCodes.BGR2GRAY)
src.CvtColor(ColorConversionCodes.GRAY2BGR)
//RGB和Gray的互相转换
src.CvtColor(ColorConversionCodes.RGB2GRAY)
src.CvtColor(ColorConversionCodes.GRAY2RGB)
//BGR和HSV的互相转换
src.CvtColor(ColorConversionCodes.BGR2HSV)
src.CvtColor(ColorConversionCodes.HSV2BGR)
//BGR和HLS的互相转换
src.CvtColor(ColorConversionCodes.BGR2HLS)
src.CvtColor(ColorConversionCodes.HLS2BGR)
这段代码中有值得几处注意的地方,就是默认我们的图像传入是BGR的 通道顺序。
效果图
等等等等,自己去组合看看把