C++ OpenCV如何提取水平和垂直线

发布时间:2021-11-26 10:41:22 作者:小新
来源:亿速云 阅读:303

C++ OpenCV如何提取水平和垂直线

在图像处理中,提取水平和垂直线是一个常见的任务。OpenCV 是一个强大的计算机视觉库,提供了多种方法来实现这一目标。本文将介绍如何使用 C++ 和 OpenCV 来提取图像中的水平和垂直线。

1. 准备工作

首先,确保你已经安装了 OpenCV 库,并且你的开发环境已经配置好。如果你还没有安装 OpenCV,可以参考官方文档进行安装。

2. 读取图像

在开始处理图像之前,我们需要先读取图像。使用 cv::imread 函数可以轻松地读取图像。

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);

    if (image.empty()) {
        std::cerr << "Could not open or find the image!" << std::endl;
        return -1;
    }

    // 显示原始图像
    cv::imshow("Original Image", image);
    cv::waitKey(0);

    return 0;
}

3. 图像预处理

在提取线条之前,通常需要对图像进行一些预处理操作,例如二值化、模糊等。这些操作可以帮助我们更好地提取线条。

3.1 二值化

二值化是将图像转换为黑白图像的过程。我们可以使用 cv::threshold 函数来实现二值化。

cv::Mat binaryImage;
cv::threshold(image, binaryImage, 128, 255, cv::THRESH_BINARY);

cv::imshow("Binary Image", binaryImage);
cv::waitKey(0);

3.2 模糊处理

模糊处理可以减少图像中的噪声,使得线条提取更加准确。我们可以使用 cv::GaussianBlur 函数来实现模糊处理。

cv::Mat blurredImage;
cv::GaussianBlur(binaryImage, blurredImage, cv::Size(5, 5), 0);

cv::imshow("Blurred Image", blurredImage);
cv::waitKey(0);

4. 提取水平和垂直线

OpenCV 提供了多种方法来提取图像中的线条,例如霍夫变换、形态学操作等。本文将介绍如何使用形态学操作来提取水平和垂直线。

4.1 创建结构元素

形态学操作需要一个结构元素(kernel),我们可以使用 cv::getStructuringElement 函数来创建结构元素。

cv::Mat horizontalKernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(image.cols / 30, 1));
cv::Mat verticalKernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, image.rows / 30));

4.2 应用形态学操作

我们可以使用 cv::morphologyEx 函数来应用形态学操作。对于水平线,我们可以使用开运算(cv::MORPH_OPEN),对于垂直线,我们可以使用闭运算(cv::MORPH_CLOSE)。

cv::Mat horizontalLines;
cv::morphologyEx(blurredImage, horizontalLines, cv::MORPH_OPEN, horizontalKernel);

cv::Mat verticalLines;
cv::morphologyEx(blurredImage, verticalLines, cv::MORPH_OPEN, verticalKernel);

cv::imshow("Horizontal Lines", horizontalLines);
cv::imshow("Vertical Lines", verticalLines);
cv::waitKey(0);

4.3 合并水平和垂直线

如果需要将水平和垂直线合并在一起,可以使用 cv::bitwise_or 函数。

cv::Mat lines;
cv::bitwise_or(horizontalLines, verticalLines, lines);

cv::imshow("Combined Lines", lines);
cv::waitKey(0);

5. 结果展示

最后,我们可以将提取的线条叠加到原始图像上,以便更直观地观察结果。

cv::Mat result;
cv::cvtColor(image, result, cv::COLOR_GRAY2BGR);
cv::addWeighted(result, 1, lines, 1, 0, result);

cv::imshow("Result", result);
cv::waitKey(0);

6. 完整代码

以下是完整的代码示例:

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 读取图像
    cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);

    if (image.empty()) {
        std::cerr << "Could not open or find the image!" << std::endl;
        return -1;
    }

    // 显示原始图像
    cv::imshow("Original Image", image);
    cv::waitKey(0);

    // 二值化
    cv::Mat binaryImage;
    cv::threshold(image, binaryImage, 128, 255, cv::THRESH_BINARY);

    cv::imshow("Binary Image", binaryImage);
    cv::waitKey(0);

    // 模糊处理
    cv::Mat blurredImage;
    cv::GaussianBlur(binaryImage, blurredImage, cv::Size(5, 5), 0);

    cv::imshow("Blurred Image", blurredImage);
    cv::waitKey(0);

    // 创建结构元素
    cv::Mat horizontalKernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(image.cols / 30, 1));
    cv::Mat verticalKernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1, image.rows / 30));

    // 提取水平线
    cv::Mat horizontalLines;
    cv::morphologyEx(blurredImage, horizontalLines, cv::MORPH_OPEN, horizontalKernel);

    cv::imshow("Horizontal Lines", horizontalLines);
    cv::waitKey(0);

    // 提取垂直线
    cv::Mat verticalLines;
    cv::morphologyEx(blurredImage, verticalLines, cv::MORPH_OPEN, verticalKernel);

    cv::imshow("Vertical Lines", verticalLines);
    cv::waitKey(0);

    // 合并水平和垂直线
    cv::Mat lines;
    cv::bitwise_or(horizontalLines, verticalLines, lines);

    cv::imshow("Combined Lines", lines);
    cv::waitKey(0);

    // 结果展示
    cv::Mat result;
    cv::cvtColor(image, result, cv::COLOR_GRAY2BGR);
    cv::addWeighted(result, 1, lines, 1, 0, result);

    cv::imshow("Result", result);
    cv::waitKey(0);

    return 0;
}

7. 总结

本文介绍了如何使用 C++ 和 OpenCV 来提取图像中的水平和垂直线。通过二值化、模糊处理和形态学操作,我们可以有效地提取图像中的线条。希望这篇文章对你有所帮助!

推荐阅读:
  1. opencv3/C++图像边缘提取的方法有哪些
  2. C++ OpenCV如何实现腐蚀与膨胀

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++ opencv

上一篇:C++ OpenCV如何实现图像亮度和对比度操作

下一篇:C#如何实现基于Socket套接字的网络通信封装

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》