如何使用 opencv 清理(去噪)图像?

问题描述 投票:0回答:1

我试图只检测较大的字母并尝试将它们保存在平面中(将其想象为一块黑板,我试图在其中打印较大的字母)。

Output

到目前为止我所做的步骤

  1. 将图像转换为 hsv。

  2. 使用 inRange 功能我创建了一个蒙版。

  3. 添加了形态关闭,以便消除较小的噪音。

  4. 终于开始绘制大字母供我参考(很少有字母未被检测到,如下所述)。

  5. 当我打印黑板时,一两个字母被省略。

我有下面的代码

#include <iostream>
#include <fstream>

#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/dnn.hpp>

using namespace cv;
using namespace cv::dnn;
using namespace std;

int main()
{
    // Load the image
    cv::Mat image = cv::imread("/run/media/cams/B4267D4B267D0F9A/Downloads/2.png");
//    cv::Mat image = cv::imread("/run/media/cams/B4267D4B267D0F9A/Downloads/np7.jpg");
//    cv::Mat image = cv::imread("/run/media/cams/B4267D4B267D0F9A/Downloads/license-plate.png");

    if (image.empty()) {
        std::cerr << "Error: Unable to load image." << std::endl;
        return -1;
    }

    cv::Mat resizedImage;
    cv::Size newSize(513, 134);

    cv::resize(image,resizedImage,newSize);

    int rows = resizedImage.rows;
    int cols  = resizedImage.cols;

    cv::Mat result(rows, cols ,resizedImage.type(), cv::Scalar(0, 0, 0));

    // Convert to grayscale
    cv::Mat gray;
    cv::cvtColor(resizedImage, gray, cv::COLOR_BGR2GRAY);
    imshow("Gray-img", gray);

    // Convert to hsv
    cv::Mat hsv;
    cv::cvtColor(resizedImage, hsv, cv::COLOR_BGR2HSV);
    imshow("HSV", hsv);

    cv:: Mat others;
    cv::cvtColor(resizedImage, others, cv::COLOR_BGR2HSV_FULL);
    imshow("HSV_FULL", others);


    cv::Mat mask;
    cv::Scalar lower(0, 0, 0);          // Lower bound
    cv::Scalar upper(179, 100, 130);    // Upper bound

    cv::inRange (others, lower, upper, mask);
    imshow("Mask", mask);

    // Create a rectangular structuring element
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));

    // Perform morphological closing
    cv::Mat close;
    cv::morphologyEx(mask, close, cv::MORPH_CLOSE, kernel, cv::Point(-1, -1), 1);

    // Merge the single-channel closed image into a 3-channel image
    cv::Mat extract;
    std::vector<cv::Mat> channels(3, close); // Create a vector with three copies of 'close'
    cv::merge(channels, extract); // Merge them into a single 3-channel image

    cv::imshow("Closed Mask", close);
//    cv::imshow("Merged Image", extract);

    // Find contours
    std::vector<std::vector<cv::Point>> contours;
//    std::vector<cv::Vec4i> hierarchy;
    cv::findContours(close, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

    for (const auto& c : contours) {
            // Get bounding rectangle
            cv::Rect boundingBox = cv::boundingRect(c);
            int area = boundingBox.width * boundingBox.height;

            // Filter based on area
            if ( area>2500 && area<5000) {
                // Draw rectangle on the original image
                cv::rectangle(resizedImage, boundingBox, cv::Scalar(36, 255, 12), 3);

                // Extract region from 'extract' and copy it to 'result'
                cv::imshow("contourssss", resizedImage);
                waitKey(0);

                // Extract region from 'extract' and copy it to 'result'
                cv::Mat roi = extract(boundingBox); // Region of Interest from extract
                roi.copyTo(result(boundingBox)); // Copy to the corresponding area in result
            }
        }

    // Display the result
    cv::imshow("Contours", result);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;

}
c++ opencv image-processing ocr object-detection
1个回答
0
投票

我可以建议尝试高斯滤波器或索贝尔滤波器吗

cv2 都有关于两者的教程。我认为高斯模糊可能会让你到达你想去的地方。

https://www.opencv-srf.com/2018/03/gaussian-blur.html https://docs.opencv.org/3.4/d2/d2c/tutorial_sobel_derivatives.html

© www.soinside.com 2019 - 2024. All rights reserved.