Commit 30d336d2 张士柳

1 个父辈 61eb66e4
...@@ -863,7 +863,7 @@ namespace eyemLib_Sharp ...@@ -863,7 +863,7 @@ namespace eyemLib_Sharp
/// <param name="nCalipers">卡尺数量</param> /// <param name="nCalipers">卡尺数量</param>
/// <param name="iSearchDirec">搜索方向(起点到终点方向的垂直方向)</param> /// <param name="iSearchDirec">搜索方向(起点到终点方向的垂直方向)</param>
/// <param name="dAmpThreshold">最小边缘幅度</param> /// <param name="dAmpThreshold">最小边缘幅度</param>
/// <param name="ccTransition">灰度值过渡的类型以确定边缘'first','all', 'negative', 'positive'</param> /// <param name="ccTransition">灰度值过渡的类型以确定边缘'all', 'negative', 'positive'</param>
/// <param name="hObject">结果</param> /// <param name="hObject">结果</param>
/// <returns></returns> /// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
...@@ -1187,7 +1187,7 @@ namespace eyemLib_Sharp ...@@ -1187,7 +1187,7 @@ namespace eyemLib_Sharp
private static extern int setSkipProcessID(int pid); private static extern int setSkipProcessID(int pid);
//圆形mark点定位 //圆形mark点定位
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMarkerTracing(EyemImage tpImage, double dThreshold, ref EyemOcsFXYR tpCircle, bool bHighAccuracy = false); private static extern int eyemMarkerTracing(EyemImage tpImage, double dThreshold, ref EyemOcsFXYR tpCircle, out EyemImage tpDstImg, bool bHighAccuracy = false);
//多功能工具 //多功能工具
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, string funcName, double dThreshold, int iNumToIgnore, ref EyemOcsFXYR tpCircle, out EyemImage tpDstImg); private static extern int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, string funcName, double dThreshold, int iNumToIgnore, ref EyemOcsFXYR tpCircle, out EyemImage tpDstImg);
...@@ -1249,7 +1249,7 @@ namespace eyemLib_Sharp ...@@ -1249,7 +1249,7 @@ namespace eyemLib_Sharp
{ {
EyemImage image; EyemImage image;
EyemImage tpDstImg = new EyemImage(); EyemImage tpDstImg = new EyemImage();
//EyemOcsFXYR tpCircle = new EyemOcsFXYR(); EyemOcsFXYR tpCircle = new EyemOcsFXYR();
//int flag = eyemImageReadRaw(fileName, 3072, 3072, 2, out ucpImage); //int flag = eyemImageReadRaw(fileName, 3072, 3072, 2, out ucpImage);
int flag = eyemImageRead(fileName, -1, out image); int flag = eyemImageRead(fileName, -1, out image);
if (flag != 0) if (flag != 0)
...@@ -1261,6 +1261,8 @@ namespace eyemLib_Sharp ...@@ -1261,6 +1261,8 @@ namespace eyemLib_Sharp
Stopwatch sw = new Stopwatch(); Stopwatch sw = new Stopwatch();
sw.Restart(); sw.Restart();
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//EyemImage image1 = new EyemImage(); EyemImage image2 = new EyemImage(); //EyemImage image1 = new EyemImage(); EyemImage image2 = new EyemImage();
//flag = eyemMatMalloc(512, 512, 1, "uint8_t", out image1); //flag = eyemMatMalloc(512, 512, 1, "uint8_t", out image1);
//flag = eyemMatMalloc(512, 512, 1, "uint8_t", out image2); //flag = eyemMatMalloc(512, 512, 1, "uint8_t", out image2);
...@@ -1280,7 +1282,16 @@ namespace eyemLib_Sharp ...@@ -1280,7 +1282,16 @@ namespace eyemLib_Sharp
//flag = eyemLibImpl(image, out tpDstImg); //flag = eyemLibImpl(image, out tpDstImg);
//flag = eyemMarkerTracing(image, 130, ref tpCircle); flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg);
Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null)
{
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
}
eyemImageFree(ref tpDstImg);
return;
#region Test Blob #region Test Blob
...@@ -1296,21 +1307,21 @@ namespace eyemLib_Sharp ...@@ -1296,21 +1307,21 @@ namespace eyemLib_Sharp
#endregion #endregion
#region Test 1DEdge #region Test 1DEdge
EyemOcsDXY tpLineSt = new EyemOcsDXY(); //EyemOcsDXY tpLineSt = new EyemOcsDXY();
tpLineSt.dX = 671; //tpLineSt.dX = 386.5;
tpLineSt.dY = 718; //tpLineSt.dY = 136.5;
EyemOcsDXY tpLineEd = new EyemOcsDXY(); //EyemOcsDXY tpLineEd = new EyemOcsDXY();
tpLineEd.dX = 858; //tpLineEd.dX = 323.5;
tpLineEd.dY = 716; //tpLineEd.dY = 40.5;
MeasureHandle hObject; //MeasureHandle hObject;
//eyemEdge1dGenMeasureRect(image, tpLineSt, tpLineEd, 10, "all", 0, 0.9, 30, out hObject); ////eyemEdge1dGenMeasureRect(image, tpLineSt, tpLineEd, 10, "all", 0, 0.9, 30, out hObject);
//eyemEdge1dGenPosRect(image, tpLineSt, tpLineEd, 50, 0, 0.9, 30, out hObject); ////eyemEdge1dGenPosRect(image, tpLineSt, tpLineEd, 50, 0, 0.9, 30, out hObject);
sw.Restart(); //sw.Restart();
eyemEdge1dFindLine(image, tpLineSt, tpLineEd, 25, 35, -1, 15, "negative", out hObject); //eyemEdge1dFindLine(image, tpLineSt, tpLineEd, 15, 3500, -1, 15, "all", out hObject);
sw.Stop(); //sw.Stop();
Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString()); //Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString());
return; //return;
//hObject.Dispose(); //hObject.Dispose();
#endregion #endregion
...@@ -1506,7 +1517,7 @@ namespace eyemLib_Sharp ...@@ -1506,7 +1517,7 @@ namespace eyemLib_Sharp
//flag = eyemMulFuncTool(image, tpRoi, "__func1", 65, 75, ref tpCircle, out tpDstImg); //flag = eyemMulFuncTool(image, tpRoi, "__func1", 65, 75, ref tpCircle, out tpDstImg);
int[] ipReelNum = new int[4]; int[] ipReelNum = new int[4];
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//获取用于制作模板的图像 //获取用于制作模板的图像
//flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg); //flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
...@@ -1566,19 +1577,19 @@ namespace eyemLib_Sharp ...@@ -1566,19 +1577,19 @@ namespace eyemLib_Sharp
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_LOWCONTRAST_PARTS" //"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_LOWCONTRAST_PARTS"
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg); //eyemCountObject(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_LARGE_PARTS", ipReelNum, out tpDstImg); //eyemCountObjectIrregularParts(image, tpRoi, file.Replace(".png", ""), "IP_LARGE_PARTS", ipReelNum, out tpDstImg);
//eyemCountObjectE(image, tpRoi, fileName, ipReelNum, out tpDstImg); //eyemCountObjectE(image, tpRoi, file.Replace(".png", ""), ipReelNum, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), tpModels[0], hModelID, ipReelNum, out tpDstImg); //eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), tpModels[0], hModelID, ipReelNum, out tpDstImg);
//eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + /*file.Replace(".png", ".tpl")*/"74d571ed-9fd4-4959-85dd-3195261e4b48.tpl", ref pNumObj, out tpDstImg); //eyemCountObjectIrregularPartsE(image, tpRoi, file.Replace(".png", ""), "D:\\模板文件\\" + /*file.Replace(".png", ".tpl")*/"74d571ed-9fd4-4959-85dd-3195261e4b48.tpl", ref pNumObj, out tpDstImg);
//移除模板 //移除模板
//flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl"); //flag = eyemRemoveModelByName(hModelID, "D:\\模板文件及图像\\df871193-6632-48f9-abfe-540c3fc49c3f.tpl");
Bitmap bitmap = eyemCvtToBitmap(tpDstImg); //Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null) //if (bitmap != null)
{ //{
//bitmap.Save("D:\\ResOut\\" + file); // //bitmap.Save("D:\\ResOut\\" + file);
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file); // bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
} //}
//< 解码测试 //< 解码测试
//int ipNum; EyemBarCode* tpResults; //int ipNum; EyemBarCode* tpResults;
......
...@@ -308,8 +308,9 @@ namespace eyemLib_Sharp ...@@ -308,8 +308,9 @@ namespace eyemLib_Sharp
/// <param name="tpCircle">结果</param> /// <param name="tpCircle">结果</param>
/// <param name="bHighAccuracy">是否是高精度定位</param> /// <param name="bHighAccuracy">是否是高精度定位</param>
/// <returns></returns> /// <returns></returns>
//圆形mark点定位
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)] [DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMarkerTracing(EyemImage tpImage, double dThreshold, ref EyemOcsFXYR tpCircle, bool bHighAccuracy = false); private static extern int eyemMarkerTracing(EyemImage tpImage, double dThreshold, ref EyemOcsFXYR tpCircle, out EyemImage tpDstImg, bool bHighAccuracy = false);
#endregion #endregion
#region 通用 #region 通用
...@@ -324,7 +325,7 @@ namespace eyemLib_Sharp ...@@ -324,7 +325,7 @@ namespace eyemLib_Sharp
private static extern void setLogCallback(TCallBack cb); private static extern void setLogCallback(TCallBack cb);
#endregion #endregion
// 日志 #region 日志
public delegate void TCallBack(string msg); public delegate void TCallBack(string msg);
public static TCallBack sld = new TCallBack(TLogCallback); public static TCallBack sld = new TCallBack(TLogCallback);
...@@ -353,12 +354,13 @@ namespace eyemLib_Sharp ...@@ -353,12 +354,13 @@ namespace eyemLib_Sharp
{ {
//算法里输出的一切日志都会在这里 //算法里输出的一切日志都会在这里
} }
#endregion
//例程 //例程
public static void eyeyTestTemplateModelMethod(string fileName) public static void eyeyTestTemplateModelMethod(string fileName)
{ {
#region //从本地读图 #region //从本地读图
//EyemImage image; //EyemImage image, tpDstImg;
//int flag = eyemImageRead(fileName, -1, out image); //int flag = eyemImageRead(fileName, -1, out image);
//if (flag != 0) //if (flag != 0)
//{ //{
...@@ -367,20 +369,22 @@ namespace eyemLib_Sharp ...@@ -367,20 +369,22 @@ namespace eyemLib_Sharp
//} //}
//EyemOcsFXYR tpCircle = new EyemOcsFXYR(); //EyemOcsFXYR tpCircle = new EyemOcsFXYR();
//flag = eyemMarkerTracing(image, 130, ref tpCircle); //flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg);
////free image ////free image
//eyemImageFree(ref image); //eyemImageFree(ref image);
//eyemImageFree(ref tpDstImg);
#endregion #endregion
#region //从内存读图 #region //从内存读图
//image = eyemCvtToEyemImage(bitmap); //image = eyemCvtToEyemImage(/*Bitmap*/);
//flag = eyemMarkerTracing(image, 130, ref tpCircle); //flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg);
////free image ////free image
//Marshal.FreeHGlobal(image.vpImage); //Marshal.FreeHGlobal(image.vpImage);
//eyemImageFree(ref tpDstImg);
#endregion #endregion
} }
......
...@@ -77,6 +77,48 @@ int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, Eyem ...@@ -77,6 +77,48 @@ int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, Eyem
return FUNC_OK; return FUNC_OK;
} }
int eyemClp2dIntersectionLineSegment(EyemOcsDABC tpLine, EyemOcsDXY tpPtSt, EyemOcsDXY tpPtEd, int *ipStatus, EyemOcsDXY &tpPoint)
{
double d1, d2;
d1 = abs(tpLine.dA*tpPtSt.dX + tpLine.dB*tpPtSt.dY + tpLine.dC) / sqrt(tpLine.dA*tpLine.dA + tpLine.dB*tpLine.dB);
if (abs(tpLine.dB) < FLT_EPSILON) {
d1 = tpPtSt.dX < -tpLine.dC / tpLine.dA ? -d1 : d1;
}
else {
d1 = tpPtSt.dY >= ((-tpLine.dA / tpLine.dB)*tpPtSt.dX - tpLine.dC / tpLine.dB) ? d1 : -d1;
}
d2 = abs(tpLine.dA*tpPtEd.dX + tpLine.dB*tpPtEd.dY + tpLine.dC) / sqrt(tpLine.dA*tpLine.dA + tpLine.dB*tpLine.dB);
if (abs(tpLine.dB) < FLT_EPSILON) {
d2 = tpPtEd.dX < -tpLine.dC / tpLine.dA ? -d2 : d2;
}
else {
d2 = tpPtEd.dY >= ((-tpLine.dA / tpLine.dB)*tpPtEd.dX - tpLine.dC / tpLine.dC) ? d2 : -d2;
}
//异号或者为0则交点存在
if (d1*d2 <= 0) {
d1 = abs(d1); d2 = abs(d2);
double k = d1 / (d1 + d2);
if ((d1 + d2 != 0) && ((tpPtSt.dX + k*(tpPtEd.dX - tpPtSt.dX) != tpPtSt.dX) || ((tpPtSt.dY + k*(tpPtEd.dY - tpPtSt.dY)) != tpPtSt.dY))) {
tpPoint.dX = tpPtSt.dX + k*(tpPtEd.dX - tpPtSt.dX); tpPoint.dY = tpPtSt.dY + k*(tpPtEd.dY - tpPtSt.dY);
*ipStatus = EYEM_CG_INTERSECTION;
}
else if (d1 + d2 == 0) {
*ipStatus = EYEM_CG_SEG1_OVERLAP_SGM2;
}
}
else {
*ipStatus = EYEM_CG_NOT_INTERSECTION;
}
return FUNC_OK;
}
int eyemClp2dIntersectionOfTwoSegments(EyemOcsDXY tpPt1St, EyemOcsDXY tpPt1Ed, EyemOcsDXY tpPt2St, EyemOcsDXY tpPt2Ed, int *ipStatus, EyemOcsDXY &tpPoint)
{
return FUNC_OK;
}
int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle) int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle)
{ {
if (abs(tpLine1.dA*tpLine2.dB - tpLine2.dA*tpLine1.dB) < EPS) { if (abs(tpLine1.dA*tpLine2.dB - tpLine2.dA*tpLine1.dB) < EPS) {
......
#include "eyemEdge1d.h" #include "eyemEdge1d.h"
static void findPeak(std::vector<double> vec, std::vector<int>& peaks) static void findPeak(int iSize, float projectMap[], float fAmpThreshold, std::vector<int>& peaks)
{ {
std::vector<int> sign; std::vector<int> sign;
for (int i = 1; i < vec.size(); i++) for (int i = 1; i < iSize; i++) {
{ auto diff = projectMap[i] - projectMap[i - 1];
auto diff = vec[i] - vec[i - 1]; if (diff < 0.0f) {
if (diff < .0)
{
sign.push_back(-1); sign.push_back(-1);
} }
else if (diff > .0) else if (diff > 0.0f) {
{
sign.push_back(1); sign.push_back(1);
} }
else else {
{
sign.push_back(0); sign.push_back(0);
} }
} }
for (int j = 1; j < sign.size(); j++) for (int j = 1; j < sign.size(); j++) {
{
int diff = sign[j] - sign[j - 1]; int diff = sign[j] - sign[j - 1];
if (diff != 0) if (diff != 0 && abs(projectMap[j]) > fAmpThreshold) {
{
peaks.push_back(j); peaks.push_back(j);
} }
} }
...@@ -47,12 +41,23 @@ static cv::Mat projectMap(const cv::Mat map, int threshold) ...@@ -47,12 +41,23 @@ static cv::Mat projectMap(const cv::Mat map, int threshold)
} }
cv::polylines(image, rejectPoint, false, cv::Scalar(0, 255, 0), 1, 8, 0); cv::polylines(image, rejectPoint, false, cv::Scalar(0, 255, 0), 1, 8, 0);
//cv::line(image, cv::Point(0, (int)MAX(height - threshold, 0)), cv::Point((int)width, (int)MAX(height - threshold, 0)), cv::Scalar(0, 255, 255), 1, 8);
cv::line(image, cv::Point(0, (int)MAX(height - threshold, 0)), cv::Point((int)width, (int)MAX(height - threshold, 0)), cv::Scalar(0, 255, 255), 1, 8);
return image; return image;
} }
void getSuperResolution(const cv::Mat &src, cv::Mat &dst, int size)
{
dst = cv::Mat::zeros(src.size()*size, src.type());
for (int i = 0; i < src.cols; i++)
{
for (int j = 0; j < src.rows; j++)
{
cv::Mat m(cv::Size(size, size), src.type(), cv::Scalar::all(src.at<uchar>(j, i)));
m.copyTo(dst(cv::Rect(i*size, j*size, size, size)));
}
}
}
int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, const char *ccSubType, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject) int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, const char *ccSubType, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject)
{ {
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage); cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
...@@ -128,7 +133,7 @@ int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY ...@@ -128,7 +133,7 @@ int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY
std::vector<double> v_filter = filter.reshape(0, 1); std::vector<double> v_filter = filter.reshape(0, 1);
std::vector<int> peeks; std::vector<int> peeks;
findPeak(v_filter, peeks); //findPeak(v_filter, peeks);
std::vector<EyemOcsDXY> *tpEdges = new std::vector<EyemOcsDXY>(); std::vector<EyemOcsDXY> *tpEdges = new std::vector<EyemOcsDXY>();
EyemOcsDXY tpEdge; EyemOcsDXY tpEdge;
...@@ -378,81 +383,7 @@ int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLi ...@@ -378,81 +383,7 @@ int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLi
return FUNC_OK; return FUNC_OK;
} }
int eyemEdge1dFitLine(IntPtr hObject, EyemOcsDABC *tpLine) int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject)
{
// cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
// if (image.empty()) {
// return FUNC_IMAGE_NOT_EXIST;
// }
// const int X = image.cols, Y = image.rows;
// //显示用
// cv::Mat cc;
// cv::cvtColor(image, cc, cv::COLOR_GRAY2BGR);
//
// //判断越界
// if (tpLineSt.dX < 0 || tpLineSt.dY < 0 || tpLineSt.dX>X || tpLineSt.dY>Y || tpLineEd.dX<0 || tpLineEd.dY<0 || tpLineEd.dX>X || tpLineEd.dY>Y) {
// return FUNC_ILLEGAL_ARGUMENT;
// }
// //主轴倾角,这个角度是带有方向的(-180°~180°)
// double t;
// t = atan2(tpLineEd.dY - tpLineSt.dY, tpLineEd.dX - tpLineSt.dX);
// //直线上的坐标
// float capLenth = (float)cv::norm(cv::Point2d(tpLineSt.dX, tpLineSt.dY) - cv::Point2d(tpLineEd.dX, tpLineEd.dY));
// //卡尺个数(后期可以根据需求更改)
// nCalipers = nCalipers >= cvFloor(capLenth) ? cvFloor(capLenth) : nCalipers;
// //步长
// float plusStep = capLenth / (float)nCalipers;
// //分配内存
// const int _Size = (nCalipers + 1)*(2 * iWhRoi + 1) * sizeof(uint8_t);
// uint8_t *pMap = (uint8_t *)malloc(_Size);
// if (NULL == pMap)
// return FUNC_NOT_ENOUGH_MEM;
// memset(pMap, 0, _Size);
// //线采样
// std::vector<cv::Mat> vmSamples;
// cv::Mat nSamples(nCalipers + 1, 2 * iWhRoi + 1, CV_8UC1, pMap);
// for (int n = 0; n <= nCalipers; n++) {
// //中轴线路径上的点
// float plusX, plusY;
// plusX = n*plusStep*(float)cos(t);
// plusY = n*plusStep*(float)sin(t);
//
// cv::Point2f pt((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY);
// std::vector<cv::Point2f> mpts;
// for (int m = -iWhRoi; m <= iWhRoi; m++) {
// //待插值坐标
// float _plusX, _plusY;
// _plusX = (float)m*(float)cos(t + iTransition*PI_BY_2) + pt.x;
// _plusY = (float)m*(float)sin(t + iTransition*PI_BY_2) + pt.y;
// //防止越界
// if (_plusX < 0 || _plusX >= X - 1 || _plusY < 0 || _plusY >= Y - 1) {
// continue;
// }
// mpts.push_back(cv::Point2f(_plusX, _plusY));
// //插值计算灰度值
// int x = (int)floor(_plusX), y = (int)floor(_plusY);
// float u = _plusX - floor(_plusX);
// float v = _plusY - floor(_plusY);
// float gv = (1.0f - u)*(1.0f - v)*(float)image.ptr<uint8_t>(y)[x] + (1.0f - u)*v*(float)image.ptr<uint8_t>(y + 1)[x] +
// u*(1.0f - v)*(float)image.ptr<uint8_t>(y)[x + 1] + u*v*(float)image.ptr<uint8_t>(y + 1)[x + 1];
// //填入灰度值
// //pMap[(iWhRoi - m) + n*nSamples.cols] = cvRound(gv);//正常图像
// //pMap[(iWhRoi + m) + n*nSamples.cols] = cvRound(gv);//沿着采样方向的不正常图像
// }
//#ifdef _DEBUG
// cv::arrowedLine(cc, mpts[0], mpts[mpts.size() - 1], cv::Scalar(0, 255, 0), 1);
//#endif
// }
// //TODO:后续考虑边界填充
//
// //释放内存(Tips:当存在越界时候在用free释放时会报错)
// free((void *)pMap);
//根据导数符号确定由暗到明和由明到暗方向,执行圆拟合与直线拟合
//std::vector<EyemOcsDXY> *tpEdges = reinterpret_cast<std::vector<EyemOcsDXY>*>(hObject);
return FUNC_OK;
}
int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int nCalipers, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject)
{ {
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone(); cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (image.empty()) { if (image.empty()) {
...@@ -462,128 +393,214 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine ...@@ -462,128 +393,214 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
//显示用 //显示用
cv::Mat cc; cv::Mat cc;
cv::cvtColor(image, cc, cv::COLOR_GRAY2BGR); cv::cvtColor(image, cc, cv::COLOR_GRAY2BGR);
//判断越界 //判断越界
if (tpLineSt.dX < 0 || tpLineSt.dY < 0 || tpLineSt.dX>X || tpLineSt.dY>Y || tpLineEd.dX<0 || tpLineEd.dY<0 || tpLineEd.dX>X || tpLineEd.dY>Y) { if (tpLineSt.dX < 0 || tpLineSt.dY < 0 || tpLineSt.dX>X || tpLineSt.dY>Y || tpLineEd.dX<0 || tpLineEd.dY<0 || tpLineEd.dX>X || tpLineEd.dY>Y) {
return FUNC_ILLEGAL_ARGUMENT; return FUNC_ILLEGAL_ARGUMENT;
} }
//主轴倾角,这个角度是带有方向的(-180°~180°) //主轴倾角
double t; double t;
t = atan2(tpLineEd.dY - tpLineSt.dY, tpLineEd.dX - tpLineSt.dX); t = atan2(tpLineEd.dY - tpLineSt.dY, tpLineEd.dX - tpLineSt.dX);
//直线上的坐标 //直线上的坐标
float capLenth = (float)cv::norm(cv::Point2d(tpLineSt.dX, tpLineSt.dY) - cv::Point2d(tpLineEd.dX, tpLineEd.dY)); float L = (float)cv::norm(cv::Point2d(tpLineSt.dX, tpLineSt.dY) - cv::Point2d(tpLineEd.dX, tpLineEd.dY));
//卡尺个数
nCalipers = nCalipers >= cvFloor(capLenth) ? cvFloor(capLenth) : nCalipers;
//步长 //步长
float plusStep = capLenth / (float)nCalipers; float plusStep = (L - (float)nCalipers*(float)iCapWidth) / ((float)nCalipers + 1.0f);
//绘制profileLine
//判断灰度值过滤类型 //drawArrowedLine("", tpLineSt, tpLineEd, cv::Scalar(255, 153, 0), 2);
int np = 1; //判断极性
if (strcmp("positive", ccTransition) == 0) { bool anyPolarity = strcmp("all", ccTransition) == 0;
np = 1; //默认过滤一半像素
} float *filterK = new float[2 * nFilterSize + 1]();
else if (strcmp("negative", ccTransition) == 0) { //定义滤波核
np = -1; for (int n = 0; n < nFilterSize; n++) {
} filterK[n] = 1;
else if (strcmp("first", ccTransition)) { filterK[2 * nFilterSize - n] = -1;
} }
//分配内存 cv::Mat whalf(cv::Size(2 * nFilterSize + 1, 1), CV_32FC1, filterK);
const int _Size = (nCalipers + 1)*(2 * iWhRoi + 1) * sizeof(uint8_t); //线采样,采用双三次插值
uint8_t *pMap = (uint8_t *)malloc(_Size); cv::Size szMap(2 * iCapLength + 1, iCapWidth + 1);
if (NULL == pMap) //结果
return FUNC_NOT_ENOUGH_MEM; std::vector<EyemOcsDXY> edgePoint;
memset(pMap, 0, _Size); for (int n = 1; n <= nCalipers; n++)
//线采样
cv::Size szMap(2 * iWhRoi + 1, nCalipers + 1);
cv::Mat nSamples(szMap, CV_8UC1, pMap);
for (int n = 0; n <= nCalipers; n++)
{ {
//中轴线路径上的点 float *pMag = new float[szMap.width*szMap.height * sizeof(float_t)];
float plusX, plusY; for (int m = 0; m <= iCapWidth; m++)
plusX = (float)n*plusStep*(float)cos(t); {
plusY = (float)n*plusStep*(float)sin(t); float plusX, plusY;
plusX = ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + m) * (float)cos(t);
cv::Point2f pLine((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY); plusY = ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + m) * (float)sin(t);
cv::Mat vmSample(1, szMap.width, CV_32FC1); //中轴线路径上的点
for (int m = -iWhRoi; m <= iWhRoi; m++) { cv::Point2f pLine((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY);
//待插值坐标 //drawPoint("", pLine, cv::Scalar(0, 0, 255), 4);
float _plusX, _plusY; for (int iR = -iCapLength; iR <= iCapLength; iR++) {
_plusX = (float)m*(float)cos(t + iSearchDirec*PI_BY_2) + pLine.x; //待插值坐标
_plusY = (float)m*(float)sin(t + iSearchDirec*PI_BY_2) + pLine.y; float _plusX, _plusY;
//防止越界 _plusX = (float)iR*(float)cos(t + iSearchDirec*CV_PI / 2.0) + pLine.x;
if (_plusX < 0 || _plusX >= X - 1 || _plusY < 0 || _plusY >= Y - 1) { _plusY = (float)iR*(float)sin(t + iSearchDirec*CV_PI / 2.0) + pLine.y;
continue; //防止越界
if (_plusX < 1 || _plusX >= X - 2 || _plusY < 1 || _plusY >= Y - 2) {
pMag[(iCapLength + iR) + m*szMap.width] = -1;
continue;
}
//drawPoint("", cv::Point2f(_plusX, _plusY), cv::Scalar(36, 127, 255), 1);
//画像素
float bb = (float)cos(t)*0.5f;
float aa = (float)sin(t)*0.5f;
cv::Point2f pt(_plusX, _plusY);
cv::Point2f pts[4];
pts[0].x = (float)(pt.x - aa - bb);
pts[0].y = (float)(pt.y + bb - aa);
pts[1].x = (float)(pt.x + aa - bb);
pts[1].y = (float)(pt.y - bb - aa);
pts[2].x = (float)(2 * pt.x - pts[0].x);
pts[2].y = (float)(2 * pt.y - pts[0].y);
pts[3].x = (float)(2 * pt.x - pts[1].x);
pts[3].y = (float)(2 * pt.y - pts[1].y);
//for (int j = 0; j < 4; j++)
//{
// drawLine("", pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0));
//}
//整数部分
int x = cvRound(_plusX), y = cvRound(_plusY);
//小数部分
float u = abs(_plusX - ((float)x + 0.5f));
float v = abs(_plusY - ((float)y - 1.0f + 0.5f));
//插值计算灰度值
float gv = (1.0f - v)*(image.ptr<uint8_t>(y - 1)[x] * (1.0f - u) + image.ptr<uint8_t>(y - 1)[x - 1] * u)
+ v*(image.ptr<uint8_t>(y)[x] * (1.0f - u) + image.ptr<uint8_t>(y)[x - 1] * u);
//填入灰度值
pMag[(iCapLength + iR) + m*szMap.width] = gv;
} }
//插值计算灰度值
int x = (int)floor(_plusX), y = (int)floor(_plusY);
float u = _plusX - floor(_plusX);
float v = _plusY - floor(_plusY);
float gv = (1.0f - u)*(1.0f - v)*(float)image.ptr<uint8_t>(y)[x] + (1.0f - u)*v*(float)image.ptr<uint8_t>(y + 1)[x] +
u*(1.0f - v)*(float)image.ptr<uint8_t>(y)[x + 1] + u*v*(float)image.ptr<uint8_t>(y + 1)[x + 1];
//填入灰度值
vmSample.ptr<float_t>(0)[iWhRoi + m] = gv;
//pMap[(iWhRoi - m) + n*nSamples.cols] = cvRound(gv);//正常图像
//pMap[(iWhRoi + m) + n*nSamples.cols] = cvRound(gv);//沿着采样方向的不正常图像
} }
//采样位置
//定位,默认过滤一半像素 cv::Point2f midLine((float)tpLineSt.dX + ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + (float)iCapWidth / 2.0f) * (float)cos(t),
const cv::Mat whalf = (cv::Mat_<float>(1, 5) << np, np, 0, -np, -np); (float)tpLineSt.dY + ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + (float)iCapWidth / 2.0f) * (float)sin(t));
//各位置采样路径
cv::Mat map1 = projectMap(vmSample, dAmpThreshold); cv::Point2f midLineStart, midLineEnd;
midLineStart = cv::Point2f(-iCapLength*(float)cos(t + iSearchDirec*CV_PI / 2.0) + midLine.x, -iCapLength*(float)sin(t + iSearchDirec*CV_PI / 2.0) + midLine.y);
float *pMag = new float[szMap.width]; midLineEnd = cv::Point2f(iCapLength*(float)cos(t + iSearchDirec* CV_PI / 2) + midLine.x, iCapLength*(float)sin(t + iSearchDirec*CV_PI / 2.0) + midLine.y);
cv::Mat mag(cv::Size(szMap.width, 1), CV_32FC1, pMag); //采样图像
cv::sepFilter2D(vmSample, mag, CV_32F, whalf, cv::Mat::ones(1, 1, CV_32F)); cv::Mat interMap(szMap, CV_32FC1, pMag);
//计算投影
cv::Mat map2 = projectMap(mag, dAmpThreshold); cv::Mat projectedMap;
cv::reduce(interMap, projectedMap, 0, cv::REDUCE_AVG, CV_32F);
//计算幅度最大值 //差分过滤(TODO:加高斯滤波)
float maxVal = *std::max_element(pMag, pMag + szMap.width); float *pFilteredMap = new float[szMap.width * sizeof(float_t)];
float dist = (float)std::distance(pMag, std::max_element(pMag, pMag + szMap.width)); cv::Mat filteredMap(cv::Size(szMap.width, 1), CV_32FC1, pFilteredMap);
cv::sepFilter2D(projectedMap, filteredMap, CV_32F, whalf, cv::Mat::ones(1, 1, CV_32F));
//遍历幅度值 //投影峰值查找
for (int i = 0; i < szMap.width; i++) { std::vector<int> peeks;
findPeak(szMap.width, pFilteredMap, (float)dAmpThreshold, peeks);
} //存在满足幅度值的边缘
if (!peeks.empty()) {
//最终坐标 float dist = 0; bool found = false;
cv::Point2f pSt, pEd; //判断灰度值过滤类型
pSt = cv::Point2f(-iWhRoi*(float)cos(t + iSearchDirec*PI_BY_2) + pLine.x, -iWhRoi*(float)sin(t + iSearchDirec*PI_BY_2) + pLine.y); if (anyPolarity) {
pEd = cv::Point2f(iWhRoi*(float)cos(t + iSearchDirec*PI_BY_2) + pLine.x, iWhRoi*(float)sin(t + iSearchDirec*PI_BY_2) + pLine.y); //不分极性
//阈值限定,计算亚像素坐标 float maxDist = 0; int maxPos = 0;
if (maxVal > dAmpThreshold) { for (auto&peek : peeks) {
int l, m, r; float a, b, c, u; if (abs(pFilteredMap[peek]) > maxDist) {
m = (int)dist; maxDist = abs(pFilteredMap[peek]);
l = m - 1 < 0 ? m : m - 1; maxPos = peek;
r = m + 1 >= szMap.width ? m : m + 1; }
}
a = pMag[l]; b = pMag[m]; found = true;
c = pMag[r]; dist = (float)maxPos;
//存在异常,无法计算亚像素坐标
float dstX, dstY;
if (abs(a - b - b + c) > EPS) {
u = 0.5f*(a - c) / (a - b - b + c);
dstX = pSt.x + (dist + 0.5f + u)*(float)cos(t + iSearchDirec*PI_BY_2);
dstY = pSt.y + (dist + 0.5f + u)*(float)sin(t + iSearchDirec*PI_BY_2);
} }
else { else if (strcmp("positive", ccTransition) == 0) {
dstX = pSt.x + (dist + 0.5f)*(float)cos(t + iSearchDirec*PI_BY_2); int maxPos = 0;
dstY = pSt.y + (dist + 0.5f)*(float)sin(t + iSearchDirec*PI_BY_2); for (auto&peek : peeks) {
if (pFilteredMap[peek] > 0) {
maxPos = peek;
found = true;
break;
}
}
dist = (float)maxPos;
} }
cc.ptr<cv::Vec3b>(cvRound(dstY))[cvRound(dstX)] = cv::Vec3b(0, 255, 255); else if (strcmp("negative", ccTransition) == 0) {
} int maxPos = 0;
for (auto&peek : peeks) {
if (pFilteredMap[peek] < 0) {
maxPos = peek;
found = true;
break;
}
}
dist = (float)maxPos;
}
//阈值限制,计算亚像素坐标
if (found) {
int l, m, r; float a, b, c, u;
m = (int)dist;
l = m - 1 < 0 ? m : m - 1;
r = m + 1 >= szMap.width ? m : m + 1;
a = pFilteredMap[l]; b = pFilteredMap[m];
c = pFilteredMap[r];
u = 0.5f*(a - c) / (a - b - b + c);
#ifdef _DEBUG //定位结果
//cv::arrowedLine(cc, pSt, pEd, cv::Scalar(0, 255, 0), 1); float dstX, dstY;
#endif dstX = midLineStart.x + (dist + u)*(float)cos(t + iSearchDirec* CV_PI / 2.0);
dstY = midLineStart.y + (dist + u)*(float)sin(t + iSearchDirec* CV_PI / 2.0);
//drawPoint("", cv::Point2f(dstX, dstY), cv::Scalar(0, 0, 255), 2);
//edgePoint.push_back(EdgePoint(0, dstX, dstY, 0, 0, true));
}
}
//作图显示用
cv::Mat cc;
cv::cvtColor(image, cc, cv::COLOR_GRAY2BGR);
//drawArrowedLine("", midLineStart, midLineEnd, cv::Scalar(0, 255, 0), 2);
cv::arrowedLine(cc, midLineStart, midLineEnd, cv::Scalar(0, 255, 0), 1);
//画卡尺
float bb = (float)cos(t)*0.5f;
float aa = (float)sin(t)*0.5f;
cv::Point2f pt(midLine.x, midLine.y);
cv::Point2f pts[4];
pts[0].x = (float)(pt.x - aa * szMap.width - bb * szMap.height);
pts[0].y = (float)(pt.y + bb * szMap.width - aa * szMap.height);
pts[1].x = (float)(pt.x + aa * szMap.width - bb * szMap.height);
pts[1].y = (float)(pt.y - bb * szMap.width - aa * szMap.height);
pts[2].x = (float)(2 * pt.x - pts[0].x);
pts[2].y = (float)(2 * pt.y - pts[0].y);
pts[3].x = (float)(2 * pt.x - pts[1].x);
pts[3].y = (float)(2 * pt.y - pts[1].y);
for (int j = 0; j < 4; j++)
{
//drawLine("", pts[j], pts[(j + 1) % 4], cv::Scalar(255, 153, 0), 2);
}
//释放资源
delete[] pMag;
pMag = NULL;
} }
//TODO:后续考虑边界填充 if (!edgePoint.empty()) {
//拟合直线
//释放内存(Tips:当存在越界时候在用free释放时会报错) //double k, b, rms;
free((void *)pMap); //findLine(edgePoint, 1, k, b, rms);
////计算交点
//cv::Point2f it;
//eyemClp2dIntersectionLineSegment(k, -1, b, 43, 25, 231, 25, it);
//画直线y=kx+b--->kx-y+b=0
//(0,P1)、(X,P2)、(P3,0)、(P4,Y)
cv::Point2f p1, p2;
//eyemClp2dIntersectionOfLineRectangle(k, -1, b, 0, 0, X, 0, X, Y, p1, p2);
//drawLine("", p1, p2, cv::Scalar(0, 255, 0), 1);
}
//cv::Mat dst;
//getSuperResolution(image, dst, 10);
//cv::cvtColor(dst, dst, cv::COLOR_GRAY2BGR);
//for (int i = 0; i < dstPts.size(); i++)
//{
// cv::circle(dst, cv::Point(int(round(dstPts[i].x * 10)), int(round(dstPts[i].y * 10))), 1, cv::Scalar(0, 255, 0), -1);
//}
////释放内存(Tips:当存在越界时候在用free释放时会报错)
//free((void *)pMap);
//释放资源
delete[] filterK;
filterK = NULL;
return FUNC_OK; return FUNC_OK;
} }
......
...@@ -462,6 +462,8 @@ extern "C" { ...@@ -462,6 +462,8 @@ extern "C" {
EXPORTS int eyemClp2dVerticalLinePointAndLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, EyemOcsDABC &tpVertical); EXPORTS int eyemClp2dVerticalLinePointAndLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, EyemOcsDABC &tpVertical);
EXPORTS void eyemClp2dLinePointAndSlope(EyemOcsDXY tpPoint, double dSlope, EyemOcsDABC &tpLine); EXPORTS void eyemClp2dLinePointAndSlope(EyemOcsDXY tpPoint, double dSlope, EyemOcsDABC &tpLine);
EXPORTS int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDXY &tpPoint); EXPORTS int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDXY &tpPoint);
EXPORTS int eyemClp2dIntersectionLineSegment(EyemOcsDABC tpLine, EyemOcsDXY tpPtSt, EyemOcsDXY tpPtEd, int *ipStatus, EyemOcsDXY &tpPoint);
EXPORTS int eyemClp2dIntersectionOfTwoSegments(EyemOcsDXY tpPt1St, EyemOcsDXY tpPt1Ed, EyemOcsDXY tpPt2St, EyemOcsDXY tpPt2Ed, int *ipStatus, EyemOcsDXY &tpPoint);
EXPORTS int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle); EXPORTS int eyemClp2dAngleTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, double &dpAngle);
EXPORTS int eyemClp2dCenterLineOfTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDABC &tpLineC); EXPORTS int eyemClp2dCenterLineOfTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDABC &tpLineC);
EXPORTS int eyemClp2dDistancePointToLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, double &dpDist); EXPORTS int eyemClp2dDistancePointToLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, double &dpDist);
...@@ -512,8 +514,12 @@ extern "C" { ...@@ -512,8 +514,12 @@ extern "C" {
// 线交叉状态 // 线交叉状态
enum { enum {
EYEM_CG_NOT_INTERSECTION, // 未相交 EYEM_CG_NOT_INTERSECTION, // 未相交
EYEM_CG_INTERSECTION, // 相交(彼此交叉) EYEM_CG_INTERSECTION, // 相交(彼此交叉)
EYEM_CG_END1_CONTACT_END2, // 线 1 的端点和线 2 的端点接触(匹配)
EYEM_CG_END1_CONTACT_SGM2, // 与线 1 的端点以外的线接触
EYEM_CG_END2_CONTACT_SGM1, // 线 2 的端点与线 1 的端点以外的接触
EYEM_CG_SEG1_OVERLAP_SGM2 // 线 1 和线 2 重叠(如果两条线位于同一直线上)
}; };
...@@ -645,7 +651,7 @@ extern "C" { ...@@ -645,7 +651,7 @@ extern "C" {
EXPORTS int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject); EXPORTS int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int iTransition, double dSigma, double dAmpThresh, IntPtr *hObject);
EXPORTS int eyemEdge1dFitLine(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDABC *tpLine); EXPORTS int eyemEdge1dFitLine(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDABC *tpLine);
EXPORTS int eyemEdge1dFitCircle(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDXYR *tpCircle); EXPORTS int eyemEdge1dFitCircle(IntPtr hObject, int iClippingEndPoints, int iMaxIterations, double dRobustCoef, EyemOcsDXYR *tpCircle);
EXPORTS int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, int nCalipers, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject); EXPORTS int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iCapLength, int iCapWidth, int nCalipers, int iFilterSize, int iSearchDirec, double dAmpThreshold, const char *ccTransition, IntPtr *hObject);
EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject); EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject);
#ifdef __cplusplus #ifdef __cplusplus
...@@ -857,7 +863,7 @@ extern "C" { ...@@ -857,7 +863,7 @@ extern "C" {
EXPORTS int eyemReleaseModel(IntPtr &hModelID); EXPORTS int eyemReleaseModel(IntPtr &hModelID);
EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg); EXPORTS int eyemTrackFeature(EyemImage tpPrevImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum, int *ipResults, EyemImage *tpDstImg);
EXPORTS int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum); EXPORTS int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, int iRoiNum);
EXPORTS int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircle, bool bHighAccuracy = false); EXPORTS int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg, bool bHighAccuracy = false);
EXPORTS int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg); EXPORTS int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, double dThreshold, int iNumToIgnore, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg);
EXPORTS int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg); EXPORTS int eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg);
EXPORTS int eyemDrawLine(EyemImage tpImage, EyemOcsDABC tpLine); EXPORTS int eyemDrawLine(EyemImage tpImage, EyemOcsDABC tpLine);
......
此文件类型无法预览
...@@ -1727,6 +1727,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char ...@@ -1727,6 +1727,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
} }
} }
}); });
//增强到目标亮度方便显示 //增强到目标亮度方便显示
cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh)); cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh));
//去掉干扰 //去掉干扰
...@@ -7264,7 +7265,7 @@ int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, i ...@@ -7264,7 +7265,7 @@ int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, i
return FUNC_OK; return FUNC_OK;
} }
int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircle, bool bHighAccuracy) int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircle, EyemImage *tpDstImg, bool bHighAccuracy)
{ {
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone(); cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
...@@ -7281,6 +7282,23 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7281,6 +7282,23 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
cv::cvtColor(image, image, cv::COLOR_GRAY2BGR); cv::cvtColor(image, image, cv::COLOR_GRAY2BGR);
} }
//画图
cv::Mat cc = image.clone();
cv::Mat imgGray;
cv::cvtColor(image, imgGray, cv::COLOR_BGR2HSV);
cv::Mat mask1, mask2;
cv::inRange(imgGray, cv::Scalar(0, 50, 20), cv::Scalar(5, 255, 255), mask1);
cv::inRange(imgGray, cv::Scalar(175, 50, 20), cv::Scalar(180, 255, 255), mask2);
cv::Mat maskj, imageR;
cv::bitwise_or(mask1, mask2, maskj);
//膨胀部分区域
cv::bitwise_and(image, image, imageR, maskj);
image = imageR;
//归一化 //归一化
cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void { cv::parallel_for_(cv::Range(0, Y), [&](const cv::Range range)->void {
for (int y = range.start; y < range.end; y++) { for (int y = range.start; y < range.end; y++) {
...@@ -7303,7 +7321,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7303,7 +7321,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
cv::threshold(mv[2], mask, dThreshold, 255, cv::THRESH_BINARY); cv::threshold(mv[2], mask, dThreshold, 255, cv::THRESH_BINARY);
//去掉干扰 //去掉干扰
cv::morphologyEx(mask, mask, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(7, 7))); cv::morphologyEx(mask, mask, cv::MORPH_OPEN, cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)));
std::vector<std::vector<cv::Point>> contours, contourfilter; std::vector<std::vector<cv::Point>> contours, contourfilter;
cv::findContours(mask, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE); cv::findContours(mask, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
...@@ -7325,7 +7343,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7325,7 +7343,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
} }
}; };
bool typeCircle = false; bool typeCircle = true;
if (typeCircle) { if (typeCircle) {
//过滤 //过滤
std::vector<cv::Point> approx; std::vector<cv::Point> approx;
...@@ -7334,17 +7352,16 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7334,17 +7352,16 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
cv::approxPolyDP(cv::Mat(contour), approx, arcL*0.01, true); cv::approxPolyDP(cv::Mat(contour), approx, arcL*0.01, true);
if (approx.size() > 10) { if (approx.size() > 10) {
cv::Rect bbox = cv::boundingRect(contour); cv::Rect bbox = cv::boundingRect(contour);
if (MAX(bbox.width, bbox.height) > 20 && ((float)bbox.width / (float)bbox.height) > 0.85 && \ if (MIN(bbox.width, bbox.height) > 20 && ((float)bbox.width / (float)bbox.height) > 0.75 && \
((float)bbox.width / (float)bbox.height) < 1.15) { ((float)bbox.width / (float)bbox.height) < 1.25) {
//圆度 //圆度
double afa = 4.0f*CV_PI*cv::contourArea(contour, false) / std::pow(arcL, 2); double afa = 4.0f*CV_PI*cv::contourArea(contour, false) / std::pow(arcL, 2);
if (afa > 0.85) { if (afa > 0.45) {
contourfilter.push_back(contour); contourfilter.push_back(contour);
} }
} }
} }
} }
std::vector<AFA> afas; std::vector<AFA> afas;
//画图 //画图
for (auto&contour : contourfilter) { for (auto&contour : contourfilter) {
...@@ -7357,7 +7374,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7357,7 +7374,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
} }
double min_err; double min_err;
EyemOcsDXYR _tpCircle; EyemOcsDXYR _tpCircle;
eyemFitCircle((int)taPoints.size(), &taPoints[0], 15, min_err, _tpCircle); eyemFitCircle((int)taPoints.size(), &taPoints[0], 10, min_err, _tpCircle);
afas.push_back(AFA(min_err, _tpCircle)); afas.push_back(AFA(min_err, _tpCircle));
} }
...@@ -7370,6 +7387,10 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7370,6 +7387,10 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
tpCircle->fX = (float)afas[0].tpCircle.dX; tpCircle->fX = (float)afas[0].tpCircle.dX;
tpCircle->fY = (float)afas[0].tpCircle.dY; tpCircle->fY = (float)afas[0].tpCircle.dY;
tpCircle->fR = (float)afas[0].tpCircle.dR; tpCircle->fR = (float)afas[0].tpCircle.dR;
//画图
cv::rectangle(cc, cv::Rect(cv::Point2f(tpCircle->fX - 2.0f*tpCircle->fR, tpCircle->fY - 2.0f*tpCircle->fR),
cv::Point2f(tpCircle->fX + 2.0f*tpCircle->fR, tpCircle->fY + 2.0f*tpCircle->fR)), cv::Scalar(0, 255, 255), 4);
cv::drawMarker(cc, cv::Point2f(tpCircle->fX, tpCircle->fY), cv::Scalar(0, 255, 0), cv::MARKER_CROSS, 20, 1);
} }
else { else {
std::vector<AFA> rboxes; std::vector<AFA> rboxes;
...@@ -7401,6 +7422,21 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl ...@@ -7401,6 +7422,21 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
tpCircle->fY = (float)rboxes[0].tpCircle.dY; tpCircle->fY = (float)rboxes[0].tpCircle.dY;
tpCircle->fR = (float)rboxes[0].tpCircle.dR; tpCircle->fR = (float)rboxes[0].tpCircle.dR;
} }
//<输出结果图像
tpDstImg->iWidth = cc.cols; tpDstImg->iHeight = cc.rows; tpDstImg->iDepth = cc.depth(); tpDstImg->iChannels = cc.channels();
//内存尺寸
int _Size = tpDstImg->iWidth*tpDstImg->iHeight*tpDstImg->iChannels * sizeof(uint8_t);
//分配初始化内存
tpDstImg->vpImage = (uint8_t *)malloc(_Size);
if (NULL == tpDstImg->vpImage)
return FUNC_NOT_ENOUGH_MEM;
memset(tpDstImg->vpImage, 0, _Size);
//拷贝数据
memcpy(tpDstImg->vpImage, cc.data, _Size);
return FUNC_OK; return FUNC_OK;
} }
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!