Commit 8939e507 张士柳

1 个父辈 cd1e2d52
...@@ -710,10 +710,10 @@ namespace eyemLib_Sharp ...@@ -710,10 +710,10 @@ namespace eyemLib_Sharp
#region 项目 #region 项目
//普通器件 //普通器件
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObject(EyemImage tpImage, string fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, ref string pNumObj, out EyemImage tpDstImg); private static extern int eyemCountObject(EyemImage tpImage, string fileName, ref string pNumObj, out EyemImage tpDstImg);
//异型器件 //异型器件
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemCountObjectIrregularParts(EyemImage tpImage, string fileName, double dOffset, string strType, int iMaxArea, int iWinSize, ref string pNumObj, out EyemImage tpDstImg); private static extern int eyemCountObjectIrregularParts(EyemImage tpImage, string fileName, string strType, string tplName, double dMinScore, ref string pNumObj, out EyemImage tpDstImg);
//读码程序 //读码程序
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, string fileName, string strCodeType, out DataCodeHandle hObject, out EyemBarCode* tpResults, out int ipNum, bool bUseNiBlack, int iBlockSize, int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0); private static extern int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, string fileName, string strCodeType, out DataCodeHandle hObject, out EyemBarCode* tpResults, out int ipNum, bool bUseNiBlack, int iBlockSize, int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0);
...@@ -742,7 +742,6 @@ namespace eyemLib_Sharp ...@@ -742,7 +742,6 @@ namespace eyemLib_Sharp
} }
//flag = eyemImageMalloc(image.iWidth, image.iHeight, 1, "uint16_t", out image1); //flag = eyemImageMalloc(image.iWidth, image.iHeight, 1, "uint16_t", out image1);
//flag = eyemImageMalloc(image.iWidth, image.iHeight, 1, "int8_t", out image2); //flag = eyemImageMalloc(image.iWidth, image.iHeight, 1, "int8_t", out image2);
...@@ -906,7 +905,7 @@ namespace eyemLib_Sharp ...@@ -906,7 +905,7 @@ namespace eyemLib_Sharp
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2]; string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","" //"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS",""
//eyemCountObject(ucpImage, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg); //eyemCountObject(ucpImage, file.Replace(".png", ""), 35, 0, 100, 5, ref pNumObj, out tpDstImg);
//eyemCountObjectIrregularParts(ucpImage, file.Replace(".png", ""), 0d, "IP_LONG_PARTS", 100, 5, ref pNumObj, out tpDstImg); eyemCountObjectIrregularParts(image, file.Replace(".png", ""), "IP_LARGE_PARTS", "", 0.7, ref pNumObj, out tpDstImg);
//int ipNum; EyemBarCode* tpResults; //int ipNum; EyemBarCode* tpResults;
//DataCodeHandle hObject; //DataCodeHandle hObject;
//int iRes = eyemDetectAndDecode(image, tpRoi, file.Replace(".png", ""), "QR_CODE|DATA_MATRIX|CODE_39|CODE_128", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 256, 1d); //int iRes = eyemDetectAndDecode(image, tpRoi, file.Replace(".png", ""), "QR_CODE|DATA_MATRIX|CODE_39|CODE_128", out hObject, out tpResults, out ipNum, false, 11, 5, 128, 256, 1d);
......
...@@ -23,17 +23,17 @@ namespace eyemLib_Sharp ...@@ -23,17 +23,17 @@ namespace eyemLib_Sharp
//} //}
//EyemLib.eyemTest2(fileNames); //EyemLib.eyemTest2(fileNames);
//foreach (var item in fileNames) foreach (var item in fileNames)
//{
// //EyemLib.eyemReadImageTool(item);
// EyemLib.eyemReadImageTool(item);
//}
for (int i = 0; i < 1; i++)
{ {
EyemLib.eyemTestVideoCapture("D:\\插件完成检测\\视频\\cap5.mp4"); //EyemLib.eyemReadImageTool(item);
EyemLib.eyemReadImageTool(item);
} }
//for (int i = 0; i < 1; i++)
//{
// EyemLib.eyemTestVideoCapture("D:\\插件完成检测\\视频\\cap5.mp4");
//}
//for (int i = 0; i < 5000; i++) //for (int i = 0; i < 5000; i++)
//{ //{
// //EyemLib.eyemTest(fileNames); // //EyemLib.eyemTest(fileNames);
......
...@@ -832,8 +832,8 @@ extern "C" { ...@@ -832,8 +832,8 @@ extern "C" {
#endif #endif
EXPORTS int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileName, const char *ccCodeType, IntPtr *hObject, EyemBarCode **tpResult, int *ipNum, bool bUseNiBlack, int iBlockSize, const int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0); EXPORTS int eyemDetectAndDecode(EyemImage tpImage, EyemRect tpRoi, const char *ccFileName, const char *ccCodeType, IntPtr *hObject, EyemBarCode **tpResult, int *ipNum, bool bUseNiBlack, int iBlockSize, const int iRangeC, int iSymbolMin, int iSymbolMax, double dScaleUpAndDown = 0.5, double dToleErr = 0.5, double dMinorStep = 1.0);
EXPORTS bool eyemDetectAndDecodeFree(IntPtr hObject); EXPORTS bool eyemDetectAndDecodeFree(IntPtr hObject);
EXPORTS int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObject(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char * ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg); EXPORTS int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, const char * ccSubType, const char *tplName, double dMinScore, LPSTR *lpszNumObj, EyemImage *tpDstImg);
EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults); EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -100,6 +100,82 @@ static int Otsu(int hist[]) ...@@ -100,6 +100,82 @@ static int Otsu(int hist[])
return kStar; return kStar;
} }
static double getThreshVal_Otsu_8u(const cv::Mat& _src)
{
cv::Size size = _src.size();
int step = (int)_src.step;
if (_src.isContinuous())
{
size.width *= size.height;
size.height = 1;
step = size.width;
}
#ifdef HAVE_IPP
unsigned char thresh = 0;
CV_IPP_RUN_FAST(ipp_getThreshVal_Otsu_8u(_src.ptr(), step, size, thresh), thresh);
#endif
const int N = 256;
int i, j, h[N] = { 0 };
#if CV_ENABLE_UNROLLED
int h_unrolled[3][N] = {};
#endif
for (i = 0; i < size.height; i++)
{
const uchar* src = _src.ptr() + step*i;
j = 0;
#if CV_ENABLE_UNROLLED
for (; j <= size.width - 4; j += 4)
{
int v0 = src[j], v1 = src[j + 1];
h[v0]++; h_unrolled[0][v1]++;
v0 = src[j + 2]; v1 = src[j + 3];
h_unrolled[1][v0]++; h_unrolled[2][v1]++;
}
#endif
for (; j < size.width; j++)
h[src[j]]++;
}
double mu = 0, scale = 1. / (size.width*size.height);
for (i = 0; i < N; i++)
{
#if CV_ENABLE_UNROLLED
h[i] += h_unrolled[0][i] + h_unrolled[1][i] + h_unrolled[2][i];
#endif
mu += i*(double)h[i];
}
mu *= scale;
double mu1 = 0, q1 = 0;
double max_sigma = 0, max_val = 0;
for (i = 0; i < N; i++)
{
double p_i, q2, mu2, sigma;
p_i = h[i] * scale;
mu1 *= q1;
q1 += p_i;
q2 = 1. - q1;
if (std::min(q1, q2) < FLT_EPSILON || std::max(q1, q2) > 1. - FLT_EPSILON)
continue;
mu1 = (mu1 + i*p_i) / q1;
mu2 = (mu - q1*mu1) / q2;
sigma = q1*q2*(mu1 - mu2)*(mu1 - mu2);
if (sigma > max_sigma)
{
max_sigma = sigma;
max_val = i;
}
}
return max_val;
}
static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize) static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize)
{ {
int X = srcPrev.cols, Y = srcPrev.rows; int X = srcPrev.cols, Y = srcPrev.rows;
...@@ -210,7 +286,7 @@ static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize) ...@@ -210,7 +286,7 @@ static bool checkSize(cv::Mat &srcPrev, cv::Mat &mask, int &partSize)
return partSize >= 20; return partSize >= 20;
} }
int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int iMinArea, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg) int eyemCountObject(EyemImage tpImage, const char *fileName, LPSTR *lpszNumObj, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
if (src.empty()) { if (src.empty()) {
...@@ -1191,48 +1267,40 @@ int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int ...@@ -1191,48 +1267,40 @@ int eyemCountObject(EyemImage tpImage, const char *fileName, double dOffset, int
return FUNC_OK; return FUNC_OK;
} }
int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, double dOffset, const char *ccSubType, int iMaxArea, int iWinSize, LPSTR *lpszNumObj, EyemImage *tpDstImg) int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, const char *ccSubType, const char *tplName, double dMinScore, LPSTR *lpszNumObj, EyemImage *tpDstImg)
{ {
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage); cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
if (src.empty()) { if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST; return FUNC_IMAGE_NOT_EXIST;
} }
//转单通道 //转单通道图像
if (src.channels() != 1) if (src.channels() != 1)
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY); cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
cv::Mat src8U; //环鸿&佳世达图像裁剪
//环鸿&佳世达
src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone(); src = src(cv::Range(200, src.cols - 70), cv::Range(200, src.rows - 10)).clone();
//苏州公司 //苏州公司&成都纬创
//src = src(cv::Range(10, src.cols - 10), cv::Range(10, src.rows - 10)).clone(); //src = src(cv::Range(10, src.cols - 10), cv::Range(10, src.rows - 10)).clone();
//图像尺寸 //图像尺寸
int X = src.cols, Y = src.rows; int X = src.cols, Y = src.rows;
//special for suzhou
#define SUZHOU true //去除局部量斑影响(默认亮斑尺寸不大于15个像素)
#if SUZHOU cv::Mat srcTmp;
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void { cv::morphologyEx(src, srcTmp, cv::MORPH_ERODE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(15, 15)));
for (int y = range.start; y < range.end; y++)
{
for (int x = 0; x < X; x++)
{
if (((short *)src.data)[(x)+(y)*X] >= 4800)
{
((short *)src.data)[(x)+(y)*X] = 4800;
}
}
}
});
#endif
//图像增强 //图像增强
double min, max; double min, max;
cv::minMaxLoc(src, &min, &max); cv::minMaxLoc(srcTmp, &min, &max);
src.convertTo(src, CV_64FC1); src.convertTo(src, CV_64FC1);
src -= min; src -= min;
src /= (max - min); src /= (max - min);
src *= 65535; src *= 65535;
src.convertTo(src, CV_16UC1); src.convertTo(src, CV_16UC1);
//转8位灰度图
cv::Mat src8U;
src.convertTo(src8U, CV_8UC1, 1 / 255.); src.convertTo(src8U, CV_8UC1, 1 / 255.);
//用于显示 //用于显示
cv::Mat cc; cv::Mat cc;
...@@ -1265,6 +1333,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, doubl ...@@ -1265,6 +1333,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, doubl
}); });
//增强到目标亮度 //增强到目标亮度
cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh)); cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh));
//去掉干扰
cv::Mat binary, srcPrev; cv::Mat binary, srcPrev;
cv::bitwise_not(src8U, srcPrev); cv::bitwise_not(src8U, srcPrev);
//使用小料算法 //使用小料算法
...@@ -1375,6 +1444,73 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, doubl ...@@ -1375,6 +1444,73 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, doubl
//使用大料算法 //使用大料算法
else if (strcmp(ccSubType, "IP_LARGE_PARTS") == 0) else if (strcmp(ccSubType, "IP_LARGE_PARTS") == 0)
{ {
//cv::imwrite("tplResult.png", srcPrev);
int tplWidth, tplHeight, tplDstWidth, tplDstHeight;
//用八个方向的模板进行模板匹配
cv::Mat tplResult(Y, X, CV_32F, cv::Scalar(0));
//std::vector<cv::Mat> tplResults;
const float icvDirections[9] = { -180,-135,-90 ,-45,0,45 ,90,135,180 };
for (int tpl = 0; tpl < 8; tpl++)
{
cv::Mat tplMat = cv::imread("D://批量测试图像//template.png", -1);
tplWidth = tplMat.cols, tplHeight = tplMat.rows;
float t = icvDirections[tpl];
tplDstWidth = tplHeight * abs(sin(t * CV_PI / 180)) + tplWidth * abs(cos(t * CV_PI / 180));
tplDstHeight = ceil(tplWidth * abs(sin(t * CV_PI / 180)) + tplHeight * abs(cos(t * CV_PI / 180)));
cv::Mat matx23f(2, 3, CV_64F);
matx23f = cv::getRotationMatrix2D(cv::Point2f((float)tplWidth / 2.0f - 0.5f, (float)tplHeight / 2.0f - 0.5f), t, 1.0);
//由于旋转产生的偏移
matx23f.ptr<double>(0)[2] += (float)(tplDstWidth - tplWidth) / 2.0;
matx23f.ptr<double>(1)[2] += (float)(tplDstHeight - tplHeight) / 2.0;
//旋转
cv::warpAffine(tplMat, tplMat, matx23f, cv::Size((int)tplDstWidth, (int)tplDstHeight), cv::INTER_CUBIC);
//模板匹配
cv::Mat tplResult0;
cv::matchTemplate(srcPrev, tplMat, tplResult0, cv::TM_CCOEFF_NORMED);
//为什么尺寸会发生比那花
//各个方向图取最大值
cv::max(tplResult0, tplResult, tplResult);
//tplResults.push_back(tplResult);
}
////分数大于0.7才当作元件处理
//cv::Mat bin;
//bin = tplResult > dMinScore;
//std::vector<cv::Point> pts;
//cv::Mat labels, stats, centroids;
//int nccomps2 = cv::connectedComponentsWithStats(bin, labels, stats, centroids);
//for (int i = 1; i < nccomps2; i++) {
// pts.push_back(cv::Point(cvRound(centroids.ptr<double>(i)[1]), cvRound(centroids.ptr<double>(i)[0])));
//}
//for (int t = 0; t < (int)pts.size(); t++)
//{
// cv::rectangle(cc, cv::Rect(pts[t].y, pts[t].x, templ.cols, templ.rows), cv::Scalar(0, 255, 0, 255), 1);
//}
//cv::imwrite("tplResult.png", cc);
//二值化 //二值化
cv::threshold(srcPrev, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); cv::threshold(srcPrev, binary, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(75, 75))); cv::morphologyEx(binary, binary, cv::MORPH_CLOSE, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(75, 75)));
...@@ -2726,10 +2862,11 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, doubl ...@@ -2726,10 +2862,11 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, const char *fileName, doubl
filePath += "\\ResOut"; filePath += "\\ResOut";
if (_access(filePath.c_str(), 0) == -1) if (_access(filePath.c_str(), 0) == -1)
_mkdir(filePath.c_str());//不存在则创建 _mkdir(filePath.c_str());//不存在则创建
//格式化文件名 //格式化文件名
char file[256]; char file[256];
sprintf_s(file, "%s\\%s-Mark.png", filePath.c_str(), fileName); sprintf_s(file, "%s\\%s-Mark.png", filePath.c_str(), fileName);
cv::imwrite(file, cc); cv::imwrite(file, srcPrev);
return FUNC_OK; return FUNC_OK;
} }
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!