Commit 04a46a32 张士柳

1 个父辈 299c004e
...@@ -700,7 +700,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -700,7 +700,6 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
std::vector<DecodeResult> decodeResults; std::vector<DecodeResult> decodeResults;
//待解码区域,区分条码类型来识别 //待解码区域,区分条码类型来识别
std::vector<WaitArea> waitAreas; std::vector<WaitArea> waitAreas;
//判断要增加的识别,从这一步可以进行分开处理 //判断要增加的识别,从这一步可以进行分开处理
if (addOneDReader) if (addOneDReader)
{ {
...@@ -739,25 +738,27 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -739,25 +738,27 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
if (addTwoDReader) if (addTwoDReader)
{ {
//突出条码部分 //突出条码部分
cv::morphologyEx(src, srcPrev, cv::MORPH_BLACKHAT, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iBlockSize + 1, 2 * iBlockSize + 1))); cv::morphologyEx(src, srcPrev, cv::MORPH_BLACKHAT, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(4 * iBlockSize, 4 * iBlockSize)));
//二值化,用于分割粘连 //二值化,用于分割粘连
cv::Mat srcPrevBin; cv::Mat srcPrevBin;
cv::threshold(srcPrev, srcPrevBin, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); cv::threshold(srcPrev, srcPrevBin, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
// //
cv::morphologyEx(srcPrevBin, srcPrevBin, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(cvRound((double)iBlockSize / 3.), cvRound((double)iBlockSize / 3.)))); int ksize = cvRound(floor((double)iBlockSize / 3.)) > 3 ? cvRound(floor((double)iBlockSize / 3.)) : 3;
cv::morphologyEx(srcPrevBin, srcPrevBin, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(ksize, ksize)));
//断裂处连接在一起 //断裂处连接在一起
cv::morphologyEx(s2, s2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iBlockSize + 1, 2 * iBlockSize + 1))); cv::morphologyEx(s2, s2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(2 * iBlockSize + 1, 2 * iBlockSize + 1)));
//去除干扰 //去除干扰
cv::bitwise_and(srcPrevBin, s2, s2); cv::bitwise_and(srcPrevBin, s2, s2);
//对图像过滤 //对图像过滤
cv::Mat labels, stats, centroids; cv::Mat labels, stats, centroids;
int nccomps = cv::connectedComponentsWithStats(s2, labels, stats, centroids, 4); int nccomps = cv::connectedComponentsWithStats(s2, labels, stats, centroids);
//过滤连通域面积及长/宽比例不符合的,允许50%误差 //过滤连通域面积及长/宽比例不符合的,允许50%误差
std::vector<uchar> colors(nccomps + 1, 0); std::vector<uchar> colors(nccomps + 1, 0);
for (int i = 1; i < nccomps; i++) { for (int i = 1; i < nccomps; i++) {
colors[i] = 255; colors[i] = 255;
double dRate = (double)stats.ptr<int>(i)[cv::CC_STAT_WIDTH] / (double)stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]; double dRate = (double)stats.ptr<int>(i)[cv::CC_STAT_WIDTH] / (double)stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]; double dRateA = (double)stats.ptr<int>(i)[cv::CC_STAT_AREA] / ((double)stats.ptr<int>(i)[cv::CC_STAT_WIDTH] * (double)stats.ptr<int>(i)[cv::CC_STAT_HEIGHT]);
if (!((dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr)) && ((double)stats.ptr<int>(i)[cv::CC_STAT_AREA] > std::pow(20 * 1.414* dScaleUpAndDown, 2)))) if (!((dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr)) && ((double)stats.ptr<int>(i)[cv::CC_STAT_AREA] > std::pow(20 * 1.414* dScaleUpAndDown, 2)) && \
(dRateA >= 0.5*(1. - dToleErr))))
{ {
colors[i] = 0; colors[i] = 0;
} }
...@@ -784,22 +785,24 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -784,22 +785,24 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
//偏移量 //偏移量
cv::Point2f pts[4]; cv::Point2f pts[4];
rec.points(pts); rec.points(pts);
cv::Point ptStart, ptEnd;
ptStart = cv::Point((pts[0] + pts[3]) / 2.); ptEnd = cv::Point((pts[1] + pts[2]) / 2.);
//满足矩形条件与面积条件 //满足矩形条件与面积条件
double dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width); double dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width);
if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20) if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20)
{ {
int dynSize = cvRound(cv::max((double)rec.boundingRect().size().height, (double)rec.boundingRect().size().width)); int dynSize = cvRound(cv::max((double)rec.boundingRect().size().height / dScaleUpAndDown, (double)rec.boundingRect().size().width / dScaleUpAndDown));
cv::Mat waitArea = src(cv::Range(cv::max(0, cvRound(rec.center.y) - (2 * iBlockSize + dynSize / 2)), cv::min(iY - 1, cvRound(rec.center.y) + (2 * iBlockSize + dynSize / 2))), cv::Range(cv::max(0, cvRound(rec.center.x) - (2 * iBlockSize + dynSize / 2)), cv::min(iX - 1, cvRound(rec.center.x) + (2 * iBlockSize + dynSize / 2)))); //用原图来进行过滤最好
cv::Mat waitArea = realSrc(cv::Range(cv::max(0, cvRound(rec.center.y / dScaleUpAndDown) - (2 * iBlockSize + dynSize / 2)), cv::min(iRealY - 1, cvRound(rec.center.y / dScaleUpAndDown) + (2 * iBlockSize + dynSize / 2))), cv::Range(cv::max(0, cvRound(rec.center.x / dScaleUpAndDown) - (2 * iBlockSize + dynSize / 2)), cv::min(iRealX - 1, cvRound(rec.center.x / dScaleUpAndDown) + (2 * iBlockSize + dynSize / 2))));
//计算响应图 //计算响应图
cv::Mat harMap; cv::Mat harMap;
cv::cornerHarris(waitArea, harMap, iBlockSize, 3, 0.04); cv::cornerHarris(waitArea, harMap, iRealBlockSize, 3, 0.04);
// 归一化与转换 // 归一化与转换
cv::normalize(harMap, harMap, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat()); cv::normalize(harMap, harMap, 0, 255, cv::NORM_MINMAX, CV_32FC1, cv::Mat());
cv::convertScaleAbs(harMap, harMap); cv::convertScaleAbs(harMap, harMap);
//进一步判断 //进一步判断
cv::Mat m2 = harMap > calcHist(harMap); cv::Mat m2 /*= harMap > calcHist(harMap)*/;
cv::threshold(harMap, m2, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
//
cv::morphologyEx(m2, m2, cv::MORPH_DILATE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(cvRound((double)iRealBlockSize / 3.), cvRound((double)iRealBlockSize / 3.))));
//用于轮廓检测 //用于轮廓检测
std::vector<std::vector<cv::Point>> contours; std::vector<std::vector<cv::Point>> contours;
findContours(m2, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); findContours(m2, contours, cv::noArray(), cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
...@@ -814,41 +817,42 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam ...@@ -814,41 +817,42 @@ int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileNam
} }
//未过滤前 //未过滤前
cv::rectangle(showMat, cv::minAreaRect(contourAll[i]).boundingRect(), cv::Scalar(0, 0, 255), 1); cv::rectangle(showMat, cv::minAreaRect(contourAll[i]).boundingRect(), cv::Scalar(0, 0, 255), 1);
////扫描线
//cv::Point ptStart, ptEnd;
//ptStart = cv::Point(pts[0]); ptEnd = cv::Point(pts[2]);
rec = cv::minAreaRect(contourMax); rec = cv::minAreaRect(contourMax);
dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width); dRate = cv::min(rec.size.width, rec.size.height) / cv::max(rec.size.height, rec.size.width);
//判断比例 //判断比例
if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20) if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && cv::min(rec.size.width, rec.size.height) > 20)
{ {
//按照比例过滤 double dRateA = std::pow(cv::min(rec.size.height, rec.size.width), 2) / std::pow(dynSize, 2);
int flags = 0; if (dRateA >= 0.5*(1. - dToleErr))
double test_line[6]{ 0 }; {
////按照比例过滤
//int flags = 0;
//double test_line[2]{ 0 };
cv::LineIterator it(binary, ptStart, ptEnd, 4); //cv::LineIterator it(binary, ptStart, ptEnd, 4);
uint8_t future_pixel = 0; //uint8_t future_pixel = 0;
for (int n = 0; n < it.count; n++, ++it) //for (int n = 0; n < it.count; n++, ++it)
{ //{
//统计均匀性 // //统计均匀性
uint8_t next_pixel = binary.ptr<uint8_t>(it.pos().y)[it.pos().x]; // uint8_t next_pixel = binary.ptr<uint8_t>(it.pos().y)[it.pos().x];
// test_line[next_pixel % 254]++;
//统计黑白像素 // if (next_pixel != future_pixel)
test_line[flags]++; // {
if (next_pixel != future_pixel) // flags++;
{ // future_pixel = 255 - future_pixel;
flags++; // }
future_pixel = 255 - future_pixel; //}
if (flags == 6) { break; } ////判断是否满足比例
} //double dRate = cv::min(test_line[0], test_line[1]) / cv::max(test_line[0], test_line[1]);
} //if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr))
//满足比例 //{
double dRate = cv::min((test_line[0] + test_line[2] + test_line[4]), (test_line[1] + test_line[3] + test_line[5])) / cv::max((test_line[0] + test_line[2] + test_line[4]), (test_line[1] + test_line[3] + test_line[5]));
if (dRate >= (1. - dToleErr) && dRate <= (1. + dToleErr) && flags >= 6)
{
//符合特征
cv::line(showMat, ptStart, ptEnd, cv::Scalar(0, 255, 255), 1);
cv::rectangle(showMat, cv::minAreaRect(contourAll[i]).boundingRect(), cv::Scalar(0, 255, 0), 1); cv::rectangle(showMat, cv::minAreaRect(contourAll[i]).boundingRect(), cv::Scalar(0, 255, 0), 1);
//}
} }
} }
} }
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!