首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Opencv 传统形态学对填涂准考证号识别的一个例子

Opencv 传统形态学对填涂准考证号识别的一个例子

原创
作者头像
sw_deng
发布2025-10-10 17:53:24
发布2025-10-10 17:53:24
760
举报
文章被收录于专栏:答题卡识别答题卡识别

背景:.对于填涂类型的准考证号或则答案,用传统的边框检测,使用合适的阈值,将对象检测出来,然后根据排列,可以得到学号或则填涂的选项。

不足:挺依赖印刷的质量和填涂的规范性,对于大批量的识别,不能保证识别的准确性。

代码语言:txt
复制
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main()
{
    Mat img = imread("d:\\Images\\stucard\\2.jpg", cv::IMREAD_UNCHANGED);
    if (img.empty())
    {
        printf("图像无法正常加载\n");
        return 0;
    }
    Mat gray;
    if (img.channels() > 1)
        cv::cvtColor(img, gray, COLOR_RGB2GRAY);
    else
        gray = img.clone();

    Mat result_Color_img;
    cvtColor(gray, result_Color_img, COLOR_GRAY2BGR);

    cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(2.0, cv::Size(8, 8));
    cv::Mat tmpresult;
    clahe->apply(gray, tmpresult);
    cv::GaussianBlur(tmpresult, tmpresult, cv::Size(3, 3), 0);
    cv::Mat binary;
    cv::threshold(tmpresult, binary, 0, 255, cv::THRESH_BINARY_INV | cv::THRESH_OTSU);

    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(binary, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

    std::vector<cv::Rect> rectarray;
    double epsilon = 0.02;
    for (const auto& contour : contours) {
        cv::Rect rect = cv::boundingRect(contour);
        int rectsize = 0;

        if (rect.width < 60 && rect.height < 36 && rect.width>12 && rect.height >12) {

            double contourArea = cv::contourArea(contour);
            double rectArea = rect.width * rect.height;
            if (contourArea / rectArea > 0.4) {

                std::vector<cv::Point> approx;
                cv::approxPolyDP(contour, approx, epsilon * cv::arcLength(contour, true), true);
                if (approx.size() >= 4) {
                    rectarray.push_back(rect);
                    cv::rectangle(result_Color_img, rect, Scalar(0, 0, 255), 2);
                }
            }
        }
    }

    namedWindow("original", WINDOW_FREERATIO);
    int window_width = 400;
    resizeWindow("original", Size(window_width, window_width * img.rows / img.cols));
    imshow("original", result_Color_img);

    waitKey(0);
    destroyAllWindows();
    return 0;
}

结果:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档