如何用OpenCV对图像去噪并提取大字符至黑底画布
提取图像大字符到黑底画布的问题
需求
仅检测图像中的大字符,并将其提取到黑底画布中(可想象为黑板,仅在上面呈现大字符)。

已完成步骤
- 将图像转换为HSV格式
- 使用
inRange函数创建掩码 - 执行形态学闭运算以去除小噪声
- 标记大字符用于参考(但仍有部分字符未被检测到)
- 输出至黑底画布时,会遗漏1-2个字符
现有代码
#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() { // 加载图像 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 << "错误:无法加载图像。" << 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)); // 转换为灰度图 cv::Mat gray; cv::cvtColor(resizedImage, gray, cv::COLOR_BGR2GRAY); imshow("灰度图", gray); // 转换为HSV格式 cv::Mat hsv; cv::cvtColor(resizedImage, hsv, cv::COLOR_BGR2HSV); imshow("HSV图", hsv); cv:: Mat others; // 转换为HSV_FULL格式 cv::cvtColor(resizedImage, others, cv::COLOR_BGR2HSV_FULL); imshow("HSV_FULL图", others); cv::Mat mask; cv::Scalar lower(0, 0, 0); // 下界 cv::Scalar upper(179, 100, 130); // 上界 // 创建掩码 cv::inRange (others, lower, upper, mask); imshow("掩码", mask); // 创建矩形结构元素 cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); // 执行形态学闭运算 cv::Mat close; cv::morphologyEx(mask, close, cv::MORPH_CLOSE, kernel, cv::Point(-1, -1), 1); // 将单通道闭运算图像合并为三通道图像 cv::Mat extract; std::vector<cv::Mat> channels(3, close); // 创建包含3份close的向量 cv::merge(channels, extract); // 合并为单张三通道图像 cv::imshow("闭运算后的掩码", close); // cv::imshow("合并后的图像", extract); // 查找轮廓 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) { // 获取边界矩形 cv::Rect boundingBox = cv::boundingRect(c); int area = boundingBox.width * boundingBox.height; // 根据面积过滤 if ( area>2500 && area<5000) { // 在原始图像上绘制矩形 cv::rectangle(resizedImage, boundingBox, cv::Scalar(36, 255, 12), 3); // 显示轮廓标记后的图像 cv::imshow("轮廓标记", resizedImage); waitKey(0); // 从extract中提取区域并复制到result cv::Mat roi = extract(boundingBox); // 从extract中获取感兴趣区域 roi.copyTo(result(boundingBox)); // 复制到result的对应区域 } } // 显示结果 cv::imshow("提取结果", result); cv::waitKey(0); cv::destroyAllWindows(); return 0; }
内容的提问来源于stack exchange,提问作者SUMAN SINGH 2018-2022 CSE A
相关产品推荐
相关产品推荐

