/**
* libdmtx - Data Matrix Encoding/Decoding Library
* Copyright 2008, 2009 Mike Laughton. All rights reserved.
*
* See LICENSE file in the main project directory for full
* terms of use and distribution.
*
* Contact: Mike Laughton <mike@dragonflylogic.com>
*
* \file dmtxregion.c
* \brief Detect barcode regions
*/
#include "dmtx.h"
#include "dmtxstatic.h"
#define DMTX_HOUGH_RES 180
/**
* \brief Create copy of existing region struct
* \param None
* \return Initialized DmtxRegion struct
*/
extern DmtxRegion *
dmtxRegionCreate(DmtxRegion *reg)
{
DmtxRegion *regCopy;
regCopy = (DmtxRegion *)malloc(sizeof(DmtxRegion));
if(regCopy == NULL)
return NULL;
memcpy(regCopy, reg, sizeof(DmtxRegion));
return regCopy;
}
/**
* \brief Destroy region struct
* \param reg
* \return void
*/
extern DmtxPassFail
dmtxRegionDestroy(DmtxRegion **reg)
{
if(reg == NULL || *reg == NULL)
return DmtxFail;
free(*reg);
*reg = NULL;
return DmtxPass;
}
/**
* \brief Find next barcode region
* \param dec Pointer to DmtxDecode information struct
* \param timeout Pointer to timeout time (NULL if none)
* \return Detected region (if found)
*/
extern DmtxRegion *
dmtxRegionFindNext(DmtxDecode *dec, DmtxTime *timeout)
{
int locStatus;
DmtxPixelLoc loc;
DmtxRegion *reg;
/* Continue until we find a region or run out of chances */
for(;;) {
locStatus = PopGridLocation(&(dec->grid), &loc);
if(locStatus == DmtxRangeEnd)
break;
/* Scan location for presence of valid barcode region */
reg = dmtxRegionScanPixel(dec, loc.X, loc.Y);
if(reg != NULL)
return reg;
/* Ran out of time? */
if(timeout != NULL && dmtxTimeExceeded(*timeout))
break;
}
return NULL;
}
/**
* \brief Scan individual pixel for presence of barcode edge
* \param dec Pointer to DmtxDecode information struct
* \param loc Pixel location
* \return Detected region (if any)
*/
extern DmtxRegion *
dmtxRegionScanPixel(DmtxDecode *dec, int x, int y)
{
unsigned char *cache;
DmtxRegion reg;
DmtxPointFlow flowBegin;
DmtxPixelLoc loc;
loc.X = x;
loc.Y = y;
cache = dmtxDecodeGetCache(dec, loc.X, loc.Y);
if(cache == NULL)
return NULL;
if((int)(*cache & 0x80) != 0x00)
return NULL;
/* Test for presence of any reasonable edge at this location */
flowBegin = MatrixRegionSeekEdge(dec, loc);
if(flowBegin.mag < (int)(dec->edgeThresh * 7.65 + 0.5))
return NULL;
memset(®, 0x00, sizeof(DmtxRegion));
/* Determine barcode orientation */
if(MatrixRegionOrientation(dec, ®, flowBegin) == DmtxFail)
return NULL;
if(dmtxRegionUpdateXfrms(dec, ®) == DmtxFail)
return NULL;
/* Define top edge */
if(MatrixRegionAlignCalibEdge(dec, ®, DmtxEdgeTop) == DmtxFail)
return NULL;
if(dmtxRegionUpdateXfrms(dec, ®) == DmtxFail)
return NULL;
/* Define right edge */
if(MatrixRegionAlignCalibEdge(dec, ®, DmtxEdgeRight) == DmtxFail)
return NULL;
if(dmtxRegionUpdateXfrms(dec, ®) == DmtxFail)
return NULL;
CALLBACK_MATRIX(®);
/* Calculate the best fitting symbol size */
if(MatrixRegionFindSize(dec, ®) == DmtxFail)
return NULL;
/* Found a valid matrix region */
return dmtxRegionCreate(®);
}
/**
*
*
*/
DmtxPointFlow
MatrixRegionSeekEdge(DmtxDecode *dec, DmtxPixelLoc loc)
{
int i;
int strongIdx;
int channelCount;
DmtxPointFlow flow, flowPlane[3];
DmtxPointFlow flowPos, flowPosBack;
DmtxPointFlow flowNeg, flowNegBack;
channelCount = dec->image->channelCount;
/* Find whether red, green, or blue shows the strongest edge */
strongIdx = 0;
for(i = 0; i < channelCount; i++) {
flowPlane[i] = GetPointFlow(dec, i, loc, dmtxNeighborNone);
if(i > 0 && flowPlane[i].mag > flowPlane[strongIdx].mag)
strongIdx = i;
}
if(flowPlane[strongIdx].mag < 10)
return dmtxBlankEdge;
flow = flowPlane[strongIdx];
flowPos = FindStrongestNeighbor(dec, flow, +1);
flowNeg = FindStrongestNeighbor(dec, flow, -1);
if(flowPos.mag != 0 && flowNeg.mag != 0) {
flowPosBack = FindStrongestNeighbor(dec, flowPos, -1);
flowNegBack = FindStrongestNeighbor(dec, flowNeg, +1);
if(flowPos.arrive == (flowPosBack.arrive+4)%8 &&
flowNeg.arrive == (flowNegBack.arrive+4)%8) {
flow.arrive = dmtxNeighborNone;
CALLBACK_POINT_PLOT(flow.loc, 1, 1, 1);
return flow;
}
}
return dmtxBlankEdge;
}
/**
*
*
*/
DmtxPassFail
MatrixRegionOrientation(DmtxDecode *dec, DmtxRegion *reg, DmtxPointFlow begin)
{
int cross;
int minArea;
int scale;
int symbolShape;
int maxDiagonal;
DmtxPassFail err;
DmtxBestLine line1x, line2x;
DmtxBestLine line2n, line2p;
DmtxFollow fTmp;
if(dec->sizeIdxExpected == DmtxSymbolSquareAuto ||
(dec->sizeIdxExpected >= DmtxSymbol10x10 &&
dec->sizeIdxExpected <= DmtxSymbol144x144))
symbolShape = DmtxSymbolSquareAuto;
else if(dec->sizeIdxExpected == DmtxSymbolRectAuto ||
(dec->sizeIdxExpected >= DmtxSymbol8x18 &&
dec->sizeIdxExpected <= DmtxSymbol16x48))
symbolShape = DmtxSymbolRectAuto;
else
symbolShape = DmtxSymbolShapeAuto;
if(dec->edgeMax != DmtxUndefined) {
if(symbolShape == DmtxSymbolRectAuto)
maxDiagonal = (int)(1.23 * dec->edgeMax + 0.5); /* sqrt(5/4) + 10% */
else
maxDiagonal = (int)(1.56 * dec->edgeMax + 0.5); /* sqrt(2) + 10% */
}
else {
maxDiagonal = DmtxUndefined;
}
/* Follow to end in both directions */
err = TrailBlazeContinuous(dec, reg, begin, maxDiagonal);
if(err == DmtxFail || reg->stepsTotal < 40) {
TrailClear(dec, reg, 0x40);
return DmtxFail;
}
/* Filter out region candidates that are smaller than expected */
if(dec->edgeMin != DmtxUndefined) {
scale = dmtxDecodeGetProp(dec, DmtxPropScale);
if(symbolShape == DmtxSymbolSquareAuto)
minArea = (dec->edgeMin * dec->edgeMin)/(scale * scale);
else
minArea = (2 * dec->edgeMin * dec->edgeMin)/(scale * scale);
if((reg->boundMax.X - reg->boundMin.X) * (reg->boundMax.Y - reg->boundMin.Y) < minArea) {
TrailClear(dec, reg, 0x40);
return DmtxFail;
}
}
line1x = FindBestSolidLine(dec, reg, 0, 0, +1, DmtxUndefined);
if(line1x.mag < 5) {
TrailClear(dec, reg, 0x40);
return DmtxFail;
}
err = FindTravelLimits(dec, reg, &line1x);
if(line1x.distSq < 100 || line1x.devn * 10 >= sqrt((double)line1x.distSq)) {
TrailClear(dec, reg, 0x40);
return DmtxFail;
}
assert(line1x.stepPos >= line1x.stepNeg);
fTmp = FollowSeek(dec, reg, line1x.stepPos + 5);
line2p = FindBestSolidLine(dec, reg, fTmp.step, line1x.stepNeg, +1, line1x.angle);
fTmp = FollowSeek(dec, reg, line1x.stepNeg - 5);
line2n = FindBestSolidLine(dec, reg, fTmp.step, line1x.stepPos, -1, line1x.angle);
if(max(line2p.mag, line2n.mag) < 5)
return DmtxFail;
if(line2p.mag > line2n.mag) {
line2x = line2p;
err = FindTravelLimits(dec, reg, &line2x);
if(line2x.distSq < 100 || line2x.devn * 10 >= sqrt((double)line2x.distSq))
return DmtxFail;
cross = ((line1x.locPos.X - line1x.locNeg.X) * (line2x.locPos.Y - line2x.locNeg.Y)) -
((line1x.locPos.Y - line1x.locNeg.Y) * (line2x.locPos.X - line2x.locNeg.X));
if(cross > 0) {
/* Condition 2 */
reg->polarity = +1;
reg->locR = line2x.locPos;
reg->stepR = line2x.stepPos;
reg->locT = line1x.locNeg;
reg->stepT = line1x.stepNeg;
reg->leftLoc = line1x.locBeg;
reg->leftAngle = line1x.angle;
reg->bottomLoc = line2x.locBeg;
reg->bottomAngle = line2x.angle;
reg->leftLine = line1x;
reg->bottomLine = line2x;
}
else {
/* Cond
没有合适的资源?快使用搜索试试~ 我知道了~
DataMatrixDemo
共29个文件
c:22个
h:3个
cpp:2个
4星 · 超过85%的资源 需积分: 0 97 下载量 123 浏览量
2018-01-13
16:58:18
上传
评论
收藏 71KB RAR 举报
温馨提示
这是一个用qt C++做的生成DataMatrix Code的Demo,二维码的实现主要基于libdmtx-0.7.4标准库,支持中文
资源推荐
资源详情
资源评论
收起资源包目录
DataMatrixDemo.rar (29个子文件)
DataMatrixTest
datamatrixtestwidget.cpp 1KB
datamatrixtestwidget.h 431B
DataMatrixTest.pro 2KB
main.cpp 192B
libdmtx-0.7.4
dmtxscangrid.c 4KB
dmtxvector2.c 3KB
dmtxdecode.c 20KB
dmtximage.c 11KB
dmtxencodescheme.c 7KB
dmtxregion.c 52KB
dmtxencode.c 13KB
dmtxmatrix3.c 8KB
dmtxencodeascii.c 5KB
dmtx.c 2KB
dmtxsymbol.c 7KB
dmtxencodestream.c 4KB
dmtxencodebase256.c 7KB
dmtxencodeoptimize.c 13KB
dmtxreedsol.c 17KB
dmtxbytelist.c 2KB
dmtxtime.c 3KB
dmtxencodec40textx12.c 16KB
dmtxencodeedifact.c 5KB
dmtxstatic.h 16KB
dmtxmessage.c 3KB
dmtxdecodescheme.c 13KB
dmtxplacemod.c 12KB
dmtx.h 22KB
datamatrixtestwidget.ui 1KB
共 29 条
- 1
资源评论
- weixin_433173922019-10-22还可以吧,能够运行
- CHENCY198202022020-02-21还可以,不错
清心永恒
- 粉丝: 67
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功