我试图只检测较大的字母并尝试将它们保存在平面中(将其想象为一块黑板,我试图在其中打印较大的字母)。
到目前为止我所做的步骤
将图像转换为 hsv。
使用 inRange 功能我创建了一个蒙版。
添加了形态关闭,以便消除较小的噪音。
终于开始绘制大字母供我参考(很少有字母未被检测到,如下所述)。
当我打印黑板时,一两个字母被省略。
我有下面的代码
#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;
}
我可以建议尝试高斯滤波器或索贝尔滤波器吗
cv2 都有关于两者的教程。我认为高斯模糊可能会让你到达你想去的地方。
https://www.opencv-srf.com/2018/03/gaussian-blur.html https://docs.opencv.org/3.4/d2/d2c/tutorial_sobel_derivatives.html