使用libdmtx库高效识别DM码,关键是图像预处理

直接代码

void MainWindow::on_pushButton_decode_datamatrix_clicked()
{

    //ROI
    cv::Rect rect(876,172,1200,1200);
    cv::Mat Dm_image_roi = Dm_image(rect);

    cv::imshow("ROI",Dm_image_roi);
    cv::waitKey(1);

    //return;

    //Resize
    cv::Size size(Dm_image_roi.rows/2 ,Dm_image_roi.cols/2);
    cv::Mat resize_image;
    cv::resize(Dm_image_roi,resize_image,size);

    cv::imshow("Resize",resize_image);
    cv::waitKey(1);
    //return;

    //平滑
    cv::Mat blur_mat;
    cv::medianBlur(resize_image,blur_mat,5);
    cv::imshow("blur_mat",blur_mat);
    cv::waitKey(1);

    //二值化
    //cv::Mat threshold_image;
    //cv::threshold(resize_image,threshold_image,50,255,0);
    //cv::imshow("threshold",threshold_image);
    //cv::waitKey(1);
    //cv::imwrite("C:/Users/OKAGV/Desktop/threshold.bmp",threshold_image);

    //修改低于某阈值的像素值
    cv::Mat threshold_image = blur_mat.clone();
    int h = threshold_image.rows;
    int w = threshold_image.cols;
    int dims = threshold_image.channels();

    for(int row = 0; row < h; row++) {
        for (int col = 0; col < w; col++) {

            if (dims == 1) {//灰度图像
                int pv = threshold_image.at<uchar>(row, col);

                if(pv > 70){
                    threshold_image.at<uchar>(row, col) = 255;
                }
            }

            if (dims == 3) {//彩色图像
                cv::Vec3b bgr = threshold_image.at<cv::Vec3b>(row, col);

                if(bgr[0] > 70){
                    threshold_image.at<cv::Vec3b>(row, col)[0] = 255;
                    threshold_image.at<cv::Vec3b>(row, col)[1] = 255;
                    threshold_image.at<cv::Vec3b>(row, col)[2] = 255;
                }

            }
        }
    }
    cv::imshow("threshold_image", threshold_image);
    cv::waitKey(1);

    cv::Mat open_image;
    cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(5,5));
    cv::morphologyEx(threshold_image,open_image,cv::MORPH_CLOSE,element);
    cv::imshow("open",open_image);
    cv::waitKey(1);
    //cv::imwrite("C:/Users/OKAGV/Desktop/open.bmp",open_image);

    cv::Mat dilate_image;
    cv::Mat element2 = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(5,5));
    cv::morphologyEx(open_image,dilate_image,cv::MORPH_ERODE,element2);
    cv::imshow("dilate",dilate_image);
    cv::waitKey(1);
    //cv::imwrite("C:/Users/OKAGV/Desktop/dilate.bmp",dilate_image);


    //转换为QImage
    QImage qcolor = QImage((const unsigned char*)(dilate_image.data),
                           dilate_image.cols, dilate_image.rows, dilate_image.step,
                           QImage::Format_RGB888);


    QTime time;
    time.start();
    QImage img = qcolor;                 //globalImg2;
    if(img.isNull())
    {
        QMessageBox::information(this,"信息","打开文件失败");
    }
    else
    {
        DmtxMessage *msg;
        DmtxRegion *reg;
        QImage src =img.copy();
        DmtxImage *imgdtx;
        QPixmap pix=QPixmap::fromImage(src);
        QString str;
        int leftLineAngle;
        int bottomLineAngle;
        int cornerx;
        int cornery;

        //qDebug()<<"src.format() "<<src.format();

        if(src.format()==QImage::Format_Mono)
        {
        src=src.convertToFormat(QImage::Format_ARGB32);
        //qDebug()<<"转换后:src.format() "<<src.format();
        }

        int pack=DmtxPack32bppXRGB;
        switch(src.format())
            {
            case QImage::Format_ARGB32:
            pack=DmtxPack32bppXRGB;
            break;
            case QImage::Format_RGB32:
            pack=DmtxPack32bppXRGB;
            break;
            case QImage::Format_RGB888:
            pack=DmtxPack24bppRGB;
            break;
            case QImage::Format_Indexed8:
            pack=DmtxPack8bppK;
            break;
            case  QImage::Format_Grayscale8:
            pack=DmtxPack8bppK;
            }

        // 增加超时时间。
        DmtxTime beginTime = dmtxTimeNow();	// 根据系统设置情况,获得当前时间
        long timeout_ms = 2000;
        DmtxTime stopTime = dmtxTimeAdd(beginTime, timeout_ms);	// 增加xx ms

        imgdtx = dmtxImageCreate(src.bits(),src.width(),src.height(),pack);
        Q_ASSERT(imgdtx != NULL);

        DmtxDecode *dec = dmtxDecodeCreate(imgdtx, 1);
        Q_ASSERT(dec != NULL);

        reg = dmtxRegionFindNext(dec,&stopTime);	// 如果超时则认为没有找到
        // assert(reg != NULL);

        if(dmtxTimeExceeded(stopTime))
        {
             //qDebug()<<"超时";
             QMessageBox::information(this,"信息","decode timeout");
        }
       else
        {
            if (reg != NULL)
            {
                msg = dmtxDecodeMatrixRegion(dec, reg, DmtxUndefined);
                if (msg != NULL)
                {
                    //                    cout << msg->output << endl;
                    //                    cout << msg->outputIdx << endl;

                    std::string strout = (char*)msg->output;//解码信息
                    str=QString::fromStdString(strout);
                    QString outmsg=QString("<font color=\"#00FF00\">%1</font>").arg(QString::fromStdString(strout));
                    ui->textEdit->setText(outmsg);

                    //  qDebug()<<"reg->leftAngle "<<reg->leftAngle;
                    //  qDebug()<<"reg->leftAngle "<<reg->bottomAngle;
                    //   qDebug()<<"reg->finalPos.X "<<reg->finalPos.X;
                    //   qDebug()<<"reg->finalPos.Y "<<reg->finalPos.Y;
                    //qDebug()<<"reg->leftLine.mag"<<reg->leftLine.mag;
                    //qDebug()<<"reg->leftLine.hOffset"<<reg->leftLine.hOffset;
                    //qDebug()<<"reg->leftLine.stepBeg"<<reg->leftLine.stepBeg;
                    //qDebug()<<"reg->leftLine.stepPos"<<reg->leftLine.stepPos;
                    //qDebug()<<"reg->leftLine.stepNeg"<<reg->leftLine.stepNeg;
                    //qDebug()<<"reg->leftLine.distSq"<<reg->leftLine.distSq;
                    //qDebug()<<"reg->leftLine.locBeg.X "<<reg->leftLine.locBeg.X;
                    //qDebug()<<"reg->leftLine.locBeg.Y "<<reg->leftLine.locBeg.Y;

//                    qDebug()<<"reg->leftLine.locPos.X "<<reg->leftLine.locPos.X;//准的
//                    qDebug()<<"reg->leftLine.locPos.Y "<<reg->leftLine.locPos.Y;//准的
//                    qDebug()<<"reg->leftLine.locNeg.X "<<reg->leftLine.locNeg.X;//准的
//                    qDebug()<<"reg->leftLine.locNeg.Y "<<reg->leftLine.locNeg.Y;//准的
//                    qDebug()<<"bottomLine.locPos.X "<<reg->bottomLine.locPos.X;
//                    qDebug()<<"bottomLine.locPos.Y "<<reg->bottomLine.locPos.Y;
//                    qDebug()<<"bottomLine.locNeg.X "<<reg->bottomLine.locNeg.X;
//                    qDebug()<<"bottomLine.locNeg.y "<<reg->bottomLine.locNeg.Y;

                    QPainter p;
                    p.begin(&pix);
                    p.setPen(QPen(Qt::blue, 2));
                    p.drawEllipse(reg->leftLine.locPos.X-5,pix.height()-reg->leftLine.locPos.Y-5, 10, 10);//准的
                    p.setPen(QPen(Qt::yellow, 2));
                    p.drawEllipse(reg->leftLine.locNeg.X-5,img.height()-reg->leftLine.locNeg.Y-5, 10, 10);//准的

                    p.setPen(QPen(Qt::darkRed, 2));
                    p.drawEllipse(reg->bottomLine.locPos.X-5,img.height()-reg->bottomLine.locPos.Y-5, 10, 10);//准的
                    p.setPen(QPen(Qt::darkGreen, 2));
                    p.drawEllipse(reg->bottomLine.locNeg.X-5,img.height()-reg->bottomLine.locNeg.Y-5, 10, 10);//准的

                    int lineOriginX=(reg->leftLine.locNeg.X+reg->bottomLine.locPos.X)/2;
                    int lineOriginY=img.height()-(reg->leftLine.locNeg.Y+reg->bottomLine.locPos.Y)/2;
                    int lineLeftX=reg->leftLine.locPos.X;
                    int lineLeftY=pix.height()-reg->leftLine.locPos.Y;
                    int lineBottomX=reg->bottomLine.locNeg.X;
                    int lineBottomY=img.height()-reg->bottomLine.locNeg.Y;

                    p.setPen(QPen(Qt::red, 2));
                    p.drawLine(lineOriginX,lineOriginY,lineLeftX,lineLeftY);
                    p.drawLine(lineOriginX,lineOriginY,lineBottomX,lineBottomY);
                    p.end();

                    leftLineAngle=reg->leftLine.angle;
                    bottomLineAngle=reg->bottomAngle;
                    cornerx=lineOriginX;
                    cornery=lineOriginY;

                    dmtxMessageDestroy(&msg);
                }
                else
                {
                    //qDebug()<<"无法检测到2";
                    QMessageBox::information(this,"信息","无法检测到2");
                }
                dmtxRegionDestroy(&reg);
            }
            else
            {
                //qDebug()<<"无法检测到1";
                QMessageBox::information(this,"信息","无法检测到1");
            }

        }

        dmtxDecodeDestroy(&dec);
        dmtxImageDestroy(&imgdtx);

        //qDebug()<<time.elapsed()/1000.0<<"s";

        ui->label_data_matrix->clear();
//        src=src.scaled(ui->label->width(),ui->label->height(),Qt::KeepAspectRatio);//Qt::KeepAspectRatio自适应大小,不变形
//        ui->label->setPixmap(QPixmap::fromImage(src));//QImage 显示速度慢
        pix=pix.scaled(ui->label_data_matrix->width(),ui->label_data_matrix->height(),Qt::KeepAspectRatio);//Qt::KeepAspectRatio自适应大小,不变形
        ui->label_data_matrix->setPixmap(pix);

        ui->label_base->clear();
        QString base_str=str.left(8);
        QString label_base_text=QString("信息:左边 %1°底边 %2°角点X %3 角点Y %4 内容 %5..").
                arg(leftLineAngle).arg(bottomLineAngle).arg(cornerx).arg(cornery).arg(base_str);
        ui->label_base->setText(label_base_text);

        QString timestr= QString("解码耗时 ")
                        + QString::number(time.elapsed())
                        + QString(" ms");
        ui->label_time->setText(timestr);
    }

    //dataMatrixDecode();//简化版本
}

其中预处理中最关键的是,自己测试的时候也有蒙的成分,但是效果很好

    //修改低于某阈值的像素值
    cv::Mat threshold_image = blur_mat.clone();
    int h = threshold_image.rows;
    int w = threshold_image.cols;
    int dims = threshold_image.channels();

    for(int row = 0; row < h; row++) {
        for (int col = 0; col < w; col++) {

            if (dims == 1) {//灰度图像
                int pv = threshold_image.at<uchar>(row, col);

                if(pv > 70){
                    threshold_image.at<uchar>(row, col) = 255;
                }
            }

            if (dims == 3) {//彩色图像
                cv::Vec3b bgr = threshold_image.at<cv::Vec3b>(row, col);

                if(bgr[0] > 70){
                    threshold_image.at<cv::Vec3b>(row, col)[0] = 255;
                    threshold_image.at<cv::Vec3b>(row, col)[1] = 255;
                    threshold_image.at<cv::Vec3b>(row, col)[2] = 255;
                }

            }
        }
    }
    cv::imshow("threshold_image", threshold_image);
    cv::waitKey(1);

附图一张
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

可峰科技

生活不易

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值