本节内容在上一节理论的基础上进行实操学习。案例框架在winfrom窗体程序上运行。
读取图片
首先在程序Debug目录下新建个test文件,存入一张图片(jpg格式)
string imagePath = @"test\ball.jpg";\\文件地址
Mat src = Cv2.ImRead(imagePath, ImreadModes.Color);
string windowName = "Display Window";\\窗体名称
Cv2.ImShow(windowName, src);
Cv2.WaitKey(0); // 等待用户按键,参数为0时表示无限等待
图片灰度图
总是提图像灰度化,究竟图像灰度是为什么呢?
首先,灰度化可以简化图像处理过程。灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),其灰度范围为0~255。这种表示方式可以大大减小图像对系统资源的占用,提高图像处理速度,降低后续图像特征提取的难度。
其次,灰度化有助于提取图像的有效信息。灰度图像只包含亮度信息,而不包含颜色信息,这使得图像识别算法可以更加专注于提取图像的纹理特征,避免颜色对图像识别造成的干扰和误差。例如,在人脸识别、车牌识别等应用中,灰度化后的图像能更准确地反映目标的形状和结构信息。
此外,灰度化还可以避免条带失真。灰度图像的精度刚好能够避免可见的条带失真,使得图像在显示和保存时更加清晰和准确。
Mat src = Cv2.ImRead(imagePath, ImreadModes.Grayscale);\\选择灰度图
string windowName = "Gary";
Cv2.ImShow(windowName, src);
Cv2.WaitKey(0); // 等待用户按键,参数为0时表示无限等待
图片二值化
图像二值化,它将图像的像素值转换为只有两种可能的值,通常是0(黑色)和255(白色)。这个过程涉及到设置一个阈值,然后将图像中所有像素的灰度值与该阈值进行比较。如果像素值低于阈值,则将其设置为0(或黑色);如果像素值高于或等于阈值,则将其设置为255(或白色)。
Mat src = Cv2.ImRead(imagePath, ImreadModes.Color);
// 创建输出图像
Mat dst = new Mat();
// 二值化,这里使用简单的阈值方法,你可以根据需要选择其他方法
Cv2.Threshold(src, dst, 170, 255, ThresholdTypes.Binary);
// 保存二值化后的图像
Cv2.ImWrite("output.jpg", dst);
string windowName = "Binary";
Cv2.ImShow(windowName, dst);
Cv2.WaitKey(0);
在这个例子中,我们使用了简单的阈值方法,并设置了阈值为 170,这意味着所有像素值小于 170 的像素将被设置为 0(黑色),而所有像素值大于或等于 170 的像素将被设置为 255(白色).
当然OenCVSharp对于阈值的选择,也提供自适应阈值处理。例如大津法(Otsu's method)等算法,用于自动计算二值化时的最佳阈值。这种方法尤其适用于那些前景和背景灰度值差异较大的图像。大津法的原理这里就不详细解释,感兴趣的小伙伴可以自行查阅。
// 使用Otsu's方法自动计算最佳阈值并进行二值化
double thresholdValue = 0; // 用于存储计算出的最佳阈值
Cv2.Threshold(src, dst, 0, 255, ThresholdTypes.Otsu | ThresholdTypes.Binary, thresholdValue);
// 输出最佳阈值
Console.WriteLine("Optimal threshold value: " + thresholdValue);
// 显示原始图像和二值化后的图像
Cv2.ImShow("Original Image", src);
Cv2.ImShow("Binary Image", dst);
// 等待用户按键后关闭窗口
Cv2.WaitKey(0);
效果图
如果按照以上步骤,我们会发现二值化的图片与原图相差不大,不利于识别特征物体。这是由于我们未先将图片转化为灰度图。我们对图片二值化的基础应正确地将图像转换为灰度图。
Mat src = Cv2.ImRead(imagePath, ImreadModes.Grayscale);
// 创建输出图像
Mat dst = new Mat();
// 二值化,这里使用简单的阈值方法,你可以根据需要选择其他方法
Cv2.Threshold(src, dst, 190, 255, ThresholdTypes.Binary);
// 保存二值化后的图像
Cv2.ImWrite("output.jpg", dst);
string windowName = "Binary";
Cv2.ImShow(windowName, dst);
Cv2.WaitKey(0);
养成良好的学习习惯,学一步理解一步。接下来我会加快学习的步伐。