直接代码
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(®);
}
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);
附图一张