Commit 30d336d2 张士柳

1 个父辈 61eb66e4
......@@ -863,7 +863,7 @@ namespace eyemLib_Sharp
/// <param name="nCalipers">卡尺数量</param>
/// <param name="iSearchDirec">搜索方向(起点到终点方向的垂直方向)</param>
/// <param name="dAmpThreshold">最小边缘幅度</param>
/// <param name="ccTransition">灰度值过渡的类型以确定边缘'first','all', 'negative', 'positive'</param>
/// <param name="ccTransition">灰度值过渡的类型以确定边缘'all', 'negative', 'positive'</param>
/// <param name="hObject">结果</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
......@@ -1187,7 +1187,7 @@ namespace eyemLib_Sharp
private static extern int setSkipProcessID(int pid);
//圆形mark点定位
[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)]
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
{
EyemImage image;
EyemImage tpDstImg = new EyemImage();
//EyemOcsFXYR tpCircle = new EyemOcsFXYR();
EyemOcsFXYR tpCircle = new EyemOcsFXYR();
//int flag = eyemImageReadRaw(fileName, 3072, 3072, 2, out ucpImage);
int flag = eyemImageRead(fileName, -1, out image);
if (flag != 0)
......@@ -1261,6 +1261,8 @@ namespace eyemLib_Sharp
Stopwatch sw = new Stopwatch();
sw.Restart();
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//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 image2);
......@@ -1280,7 +1282,16 @@ namespace eyemLib_Sharp
//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
......@@ -1296,21 +1307,21 @@ namespace eyemLib_Sharp
#endregion
#region Test 1DEdge
EyemOcsDXY tpLineSt = new EyemOcsDXY();
tpLineSt.dX = 671;
tpLineSt.dY = 718;
EyemOcsDXY tpLineEd = new EyemOcsDXY();
tpLineEd.dX = 858;
tpLineEd.dY = 716;
MeasureHandle hObject;
//eyemEdge1dGenMeasureRect(image, tpLineSt, tpLineEd, 10, "all", 0, 0.9, 30, out hObject);
//eyemEdge1dGenPosRect(image, tpLineSt, tpLineEd, 50, 0, 0.9, 30, out hObject);
sw.Restart();
eyemEdge1dFindLine(image, tpLineSt, tpLineEd, 25, 35, -1, 15, "negative", out hObject);
sw.Stop();
Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString());
return;
//EyemOcsDXY tpLineSt = new EyemOcsDXY();
//tpLineSt.dX = 386.5;
//tpLineSt.dY = 136.5;
//EyemOcsDXY tpLineEd = new EyemOcsDXY();
//tpLineEd.dX = 323.5;
//tpLineEd.dY = 40.5;
//MeasureHandle hObject;
////eyemEdge1dGenMeasureRect(image, tpLineSt, tpLineEd, 10, "all", 0, 0.9, 30, out hObject);
////eyemEdge1dGenPosRect(image, tpLineSt, tpLineEd, 50, 0, 0.9, 30, out hObject);
//sw.Restart();
//eyemEdge1dFindLine(image, tpLineSt, tpLineEd, 15, 3500, -1, 15, "all", out hObject);
//sw.Stop();
//Console.WriteLine("时间:" + sw.ElapsedMilliseconds.ToString());
//return;
//hObject.Dispose();
#endregion
......@@ -1506,7 +1517,7 @@ namespace eyemLib_Sharp
//flag = eyemMulFuncTool(image, tpRoi, "__func1", 65, 75, ref tpCircle, out tpDstImg);
int[] ipReelNum = new int[4];
string file = fileName.Split(new string[] { "\\" }, StringSplitOptions.RemoveEmptyEntries)[2];
//获取用于制作模板的图像
//flag = eyemAchvTemplateImage(image, tpRoi, out tpDstImg);
......@@ -1566,19 +1577,19 @@ namespace eyemLib_Sharp
//"IP_SMALL_PARTS","IP_LARGE_PARTS","IP_LONG_PARTS","IP_LOWCONTRAST_PARTS"
//eyemCountObject(image, tpRoi, file.Replace(".png", ""), 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", ""), "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");
Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null)
{
//bitmap.Save("D:\\ResOut\\" + file);
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
}
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// //bitmap.Save("D:\\ResOut\\" + file);
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//< 解码测试
//int ipNum; EyemBarCode* tpResults;
......
......@@ -308,8 +308,9 @@ namespace eyemLib_Sharp
/// <param name="tpCircle">结果</param>
/// <param name="bHighAccuracy">是否是高精度定位</param>
/// <returns></returns>
//圆形mark点定位
[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
#region 通用
......@@ -324,7 +325,7 @@ namespace eyemLib_Sharp
private static extern void setLogCallback(TCallBack cb);
#endregion
// 日志
#region 日志
public delegate void TCallBack(string msg);
public static TCallBack sld = new TCallBack(TLogCallback);
......@@ -353,12 +354,13 @@ namespace eyemLib_Sharp
{
//算法里输出的一切日志都会在这里
}
#endregion
//例程
public static void eyeyTestTemplateModelMethod(string fileName)
{
#region //从本地读图
//EyemImage image;
//EyemImage image, tpDstImg;
//int flag = eyemImageRead(fileName, -1, out image);
//if (flag != 0)
//{
......@@ -367,20 +369,22 @@ namespace eyemLib_Sharp
//}
//EyemOcsFXYR tpCircle = new EyemOcsFXYR();
//flag = eyemMarkerTracing(image, 130, ref tpCircle);
//flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg);
////free image
//eyemImageFree(ref image);
//eyemImageFree(ref tpDstImg);
#endregion
#region //从内存读图
//image = eyemCvtToEyemImage(bitmap);
//image = eyemCvtToEyemImage(/*Bitmap*/);
//flag = eyemMarkerTracing(image, 130, ref tpCircle);
//flag = eyemMarkerTracing(image, 120, ref tpCircle, out tpDstImg);
////free image
//Marshal.FreeHGlobal(image.vpImage);
//eyemImageFree(ref tpDstImg);
#endregion
}
......
......@@ -77,6 +77,48 @@ int eyemClp2dIntersectionTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, Eyem
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)
{
if (abs(tpLine1.dA*tpLine2.dB - tpLine2.dA*tpLine1.dB) < EPS) {
......
#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;
for (int i = 1; i < vec.size(); i++)
{
auto diff = vec[i] - vec[i - 1];
if (diff < .0)
{
for (int i = 1; i < iSize; i++) {
auto diff = projectMap[i] - projectMap[i - 1];
if (diff < 0.0f) {
sign.push_back(-1);
}
else if (diff > .0)
{
else if (diff > 0.0f) {
sign.push_back(1);
}
else
{
else {
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];
if (diff != 0)
{
if (diff != 0 && abs(projectMap[j]) > fAmpThreshold) {
peaks.push_back(j);
}
}
......@@ -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::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;
}
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)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
......@@ -128,7 +133,7 @@ int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY
std::vector<double> v_filter = filter.reshape(0, 1);
std::vector<int> peeks;
findPeak(v_filter, peeks);
//findPeak(v_filter, peeks);
std::vector<EyemOcsDXY> *tpEdges = new std::vector<EyemOcsDXY>();
EyemOcsDXY tpEdge;
......@@ -378,81 +383,7 @@ int eyemEdge1dGenPosRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLi
return FUNC_OK;
}
int eyemEdge1dFitLine(IntPtr hObject, EyemOcsDABC *tpLine)
{
// 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)
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()) {
......@@ -462,128 +393,214 @@ int eyemEdge1dFindLine(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLine
//显示用
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 L = (float)cv::norm(cv::Point2d(tpLineSt.dX, tpLineSt.dY) - cv::Point2d(tpLineEd.dX, tpLineEd.dY));
//步长
float plusStep = capLenth / (float)nCalipers;
//判断灰度值过滤类型
int np = 1;
if (strcmp("positive", ccTransition) == 0) {
np = 1;
}
else if (strcmp("negative", ccTransition) == 0) {
np = -1;
}
else if (strcmp("first", ccTransition)) {
float plusStep = (L - (float)nCalipers*(float)iCapWidth) / ((float)nCalipers + 1.0f);
//绘制profileLine
//drawArrowedLine("", tpLineSt, tpLineEd, cv::Scalar(255, 153, 0), 2);
//判断极性
bool anyPolarity = strcmp("all", ccTransition) == 0;
//默认过滤一半像素
float *filterK = new float[2 * nFilterSize + 1]();
//定义滤波核
for (int n = 0; n < nFilterSize; n++) {
filterK[n] = 1;
filterK[2 * nFilterSize - n] = -1;
}
//分配内存
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);
//线采样
cv::Size szMap(2 * iWhRoi + 1, nCalipers + 1);
cv::Mat nSamples(szMap, CV_8UC1, pMap);
for (int n = 0; n <= nCalipers; n++)
cv::Mat whalf(cv::Size(2 * nFilterSize + 1, 1), CV_32FC1, filterK);
//线采样,采用双三次插值
cv::Size szMap(2 * iCapLength + 1, iCapWidth + 1);
//结果
std::vector<EyemOcsDXY> edgePoint;
for (int n = 1; n <= nCalipers; n++)
{
//中轴线路径上的点
float plusX, plusY;
plusX = (float)n*plusStep*(float)cos(t);
plusY = (float)n*plusStep*(float)sin(t);
cv::Point2f pLine((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY);
cv::Mat vmSample(1, szMap.width, CV_32FC1);
for (int m = -iWhRoi; m <= iWhRoi; m++) {
//待插值坐标
float _plusX, _plusY;
_plusX = (float)m*(float)cos(t + iSearchDirec*PI_BY_2) + pLine.x;
_plusY = (float)m*(float)sin(t + iSearchDirec*PI_BY_2) + pLine.y;
//防止越界
if (_plusX < 0 || _plusX >= X - 1 || _plusY < 0 || _plusY >= Y - 1) {
continue;
float *pMag = new float[szMap.width*szMap.height * sizeof(float_t)];
for (int m = 0; m <= iCapWidth; m++)
{
float plusX, plusY;
plusX = ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + m) * (float)cos(t);
plusY = ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + m) * (float)sin(t);
//中轴线路径上的点
cv::Point2f pLine((float)tpLineSt.dX + plusX, (float)tpLineSt.dY + plusY);
//drawPoint("", pLine, cv::Scalar(0, 0, 255), 4);
for (int iR = -iCapLength; iR <= iCapLength; iR++) {
//待插值坐标
float _plusX, _plusY;
_plusX = (float)iR*(float)cos(t + iSearchDirec*CV_PI / 2.0) + pLine.x;
_plusY = (float)iR*(float)sin(t + iSearchDirec*CV_PI / 2.0) + pLine.y;
//防止越界
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);//沿着采样方向的不正常图像
}
//定位,默认过滤一半像素
const cv::Mat whalf = (cv::Mat_<float>(1, 5) << np, np, 0, -np, -np);
cv::Mat map1 = projectMap(vmSample, dAmpThreshold);
float *pMag = new float[szMap.width];
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 map2 = projectMap(mag, dAmpThreshold);
//计算幅度最大值
float maxVal = *std::max_element(pMag, pMag + szMap.width);
float dist = (float)std::distance(pMag, std::max_element(pMag, pMag + szMap.width));
//遍历幅度值
for (int i = 0; i < szMap.width; i++) {
}
//最终坐标
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);
pEd = cv::Point2f(iWhRoi*(float)cos(t + iSearchDirec*PI_BY_2) + pLine.x, iWhRoi*(float)sin(t + iSearchDirec*PI_BY_2) + pLine.y);
//阈值限定,计算亚像素坐标
if (maxVal > dAmpThreshold) {
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 = pMag[l]; b = pMag[m];
c = pMag[r];
//存在异常,无法计算亚像素坐标
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);
//采样位置
cv::Point2f midLine((float)tpLineSt.dX + ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + (float)iCapWidth / 2.0f) * (float)cos(t),
(float)tpLineSt.dY + ((float)n*(plusStep + (float)iCapWidth) - (float)iCapWidth + (float)iCapWidth / 2.0f) * (float)sin(t));
//各位置采样路径
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);
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 interMap(szMap, CV_32FC1, pMag);
//计算投影
cv::Mat projectedMap;
cv::reduce(interMap, projectedMap, 0, cv::REDUCE_AVG, CV_32F);
//差分过滤(TODO:加高斯滤波)
float *pFilteredMap = new float[szMap.width * sizeof(float_t)];
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));
//投影峰值查找
std::vector<int> peeks;
findPeak(szMap.width, pFilteredMap, (float)dAmpThreshold, peeks);
//存在满足幅度值的边缘
if (!peeks.empty()) {
float dist = 0; bool found = false;
//判断灰度值过滤类型
if (anyPolarity) {
//不分极性
float maxDist = 0; int maxPos = 0;
for (auto&peek : peeks) {
if (abs(pFilteredMap[peek]) > maxDist) {
maxDist = abs(pFilteredMap[peek]);
maxPos = peek;
}
}
found = true;
dist = (float)maxPos;
}
else {
dstX = pSt.x + (dist + 0.5f)*(float)cos(t + iSearchDirec*PI_BY_2);
dstY = pSt.y + (dist + 0.5f)*(float)sin(t + iSearchDirec*PI_BY_2);
else if (strcmp("positive", ccTransition) == 0) {
int maxPos = 0;
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);
#endif
//定位结果
float dstX, dstY;
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:后续考虑边界填充
//释放内存(Tips:当存在越界时候在用free释放时会报错)
free((void *)pMap);
if (!edgePoint.empty()) {
//拟合直线
//double k, b, rms;
//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;
}
......
......@@ -462,6 +462,8 @@ extern "C" {
EXPORTS int eyemClp2dVerticalLinePointAndLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, EyemOcsDABC &tpVertical);
EXPORTS void eyemClp2dLinePointAndSlope(EyemOcsDXY tpPoint, double dSlope, EyemOcsDABC &tpLine);
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 eyemClp2dCenterLineOfTwoLines(EyemOcsDABC tpLine1, EyemOcsDABC tpLine2, EyemOcsDABC &tpLineC);
EXPORTS int eyemClp2dDistancePointToLine(EyemOcsDXY tpPoint, EyemOcsDABC tpLine, double &dpDist);
......@@ -512,8 +514,12 @@ extern "C" {
// 线交叉状态
enum {
EYEM_CG_NOT_INTERSECTION, // 未相交
EYEM_CG_INTERSECTION, // 相交(彼此交叉)
EYEM_CG_NOT_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" {
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 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);
#ifdef __cplusplus
......@@ -857,7 +863,7 @@ extern "C" {
EXPORTS int eyemReleaseModel(IntPtr &hModelID);
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 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 eyemLibImpl(EyemImage tpImage, EyemImage *tpDstImg);
EXPORTS int eyemDrawLine(EyemImage tpImage, EyemOcsDABC tpLine);
......
此文件类型无法预览
......@@ -1727,6 +1727,7 @@ int eyemCountObjectIrregularParts(EyemImage tpImage, EyemRect tpRoi, const char
}
}
});
//增强到目标亮度方便显示
cc += cv::Scalar((162 - backThresh), (162 - backThresh), (162 - backThresh));
//去掉干扰
......@@ -7264,7 +7265,7 @@ int eyemAOIForTSAV(EyemImage tpRefImg, EyemImage tpNextImg, EyemRect3 *tpRois, i
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();
......@@ -7281,6 +7282,23 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
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 {
for (int y = range.start; y < range.end; y++) {
......@@ -7303,7 +7321,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
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;
cv::findContours(mask, contours, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
......@@ -7325,7 +7343,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
}
};
bool typeCircle = false;
bool typeCircle = true;
if (typeCircle) {
//过滤
std::vector<cv::Point> approx;
......@@ -7334,17 +7352,16 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
cv::approxPolyDP(cv::Mat(contour), approx, arcL*0.01, true);
if (approx.size() > 10) {
cv::Rect bbox = cv::boundingRect(contour);
if (MAX(bbox.width, bbox.height) > 20 && ((float)bbox.width / (float)bbox.height) > 0.85 && \
((float)bbox.width / (float)bbox.height) < 1.15) {
if (MIN(bbox.width, bbox.height) > 20 && ((float)bbox.width / (float)bbox.height) > 0.75 && \
((float)bbox.width / (float)bbox.height) < 1.25) {
//圆度
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);
}
}
}
}
std::vector<AFA> afas;
//画图
for (auto&contour : contourfilter) {
......@@ -7357,7 +7374,7 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
}
double min_err;
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));
}
......@@ -7370,6 +7387,10 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
tpCircle->fX = (float)afas[0].tpCircle.dX;
tpCircle->fY = (float)afas[0].tpCircle.dY;
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 {
std::vector<AFA> rboxes;
......@@ -7401,6 +7422,21 @@ int eyemMarkerTracing(EyemImage tpImage, double dThreshold, EyemOcsFXYR *tpCircl
tpCircle->fY = (float)rboxes[0].tpCircle.dY;
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;
}
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!