Commit 29630f64 张士柳

1 个父辈 b2c1dc1c
......@@ -983,6 +983,13 @@ namespace eyemLib_Sharp
private static extern int eyemNNDetector(EyemImage tpImage, out int ipNum, ref BboxContainer container);
#endregion
#region 模板匹配
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemMakeShapeModel(EyemImage tpImage, double dContrast, double dMinContrast, int iApertureSize = 3, bool bL2gradient = false);
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemFindShapeModel(EyemImage tpImage, int iNumLevels, double dAngleStart, double dAngleExtent, double dAngleStep, double dMinContrast, double dContrast, double dGreediness, double dMinScore, bool bOptimization = true);
#endregion
#region 项目
//普通器件(仍采用旧的算法)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
......@@ -1144,12 +1151,34 @@ namespace eyemLib_Sharp
//flag = eyemLibImpl(image, tpHsvModel, out tpDstImg);
EyemImage templ, search;
flag = eyemImageRead("D://批量测试图像//template.png", -1, out templ);
if (flag != 0)
{
Console.WriteLine("读图失败!");
return;
}
flag = eyemImageRead("D://批量测试图像//search1.png", -1, out search);
if (flag != 0)
{
Console.WriteLine("读图失败!");
return;
}
flag = eyemMakeShapeModel(templ, 100, 10);
flag = eyemFindShapeModel(search, 10, 0, 90, 1, 10, 100, 0.9, 0.9);
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//return;
sw.Stop();
Console.WriteLine("时间花费" + sw.ElapsedMilliseconds.ToString());
eyemImageFree(ref templ);
eyemImageFree(ref search);
return;
//flag = eyemNormalize(ref image);
......@@ -1170,14 +1199,14 @@ namespace eyemLib_Sharp
//flag = eyemShockFilter(image, 9, 1.5, 0.5, 10, out tpDstImg);
flag = eyemNonLocalMeansFilter(image, 7, 21, 3.0, -1);
//flag = eyemNonLocalMeansFilter(image, 7, 21, 3.0, -1);
Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
if (bitmap != null)
{
bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
}
return;
//Bitmap bitmap = eyemCvtToBitmap(tpDstImg);
//if (bitmap != null)
//{
// bitmap.Save(System.Windows.Forms.Application.StartupPath + "\\ResOut\\" + file);
//}
//return;
#region Test Blob
//sw.Restart();
......
......@@ -21,6 +21,7 @@ namespace eyemLib_Sharp
foreach (var item in fileNames)
{
EyemLib.eyemReadImageTool(item);
break;
}
EyemLib.Free();
Console.Write("请按任意键继续。。。");
......
......@@ -671,12 +671,12 @@ extern "C" {
#endif
// 函数接口
EXPORTS int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, const char *ccSubType, 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 eyemEdge1dFindCircle(EyemImage tpImage, EyemOcsDXY tpPoint, int iRadius, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, 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 int eyemPolarTrans(EyemImage tpImage, EyemOcsDXY tpCenter, int iRadius, int iSapWidth);
EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject);
EXPORTS int eyemEdge1dGenMeasureRect(EyemImage tpImage, EyemOcsDXY tpLineSt, EyemOcsDXY tpLineEd, int iWhRoi, const char *ccSubType, 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 eyemEdge1dFindCircle(EyemImage tpImage, EyemOcsDXY tpPoint, int iRadius, int iCapLength, int iCapWidth, int nCalipers, int nFilterSize, 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 int eyemPolarTrans(EyemImage tpImage, EyemOcsDXY tpCenter, int iRadius, int iSapWidth);
EXPORTS bool eyemEdge1dGenMeasureFree(IntPtr hObject);
#ifdef __cplusplus
}
......@@ -691,11 +691,28 @@ extern "C" {
#endif
// 函数接口
EXPORTS int eyemEdgesPixel(EyemImage tpImage, double dThreshold, IntPtr *hObject, int *ipNum, EyemOcsDXY **hResults);
EXPORTS int eyemEdgesSubpixel(EyemImage tpImage, IntPtr *hObject, EyemOcsDXY **tpEdges, int iFilter, int iLow, int iHigh);
EXPORTS int eyemSkeleton(EyemImage tpImage, EyemImage &skeleton);
EXPORTS int eyemSobelAmp(EyemImage tpImage, EyemImage &ImaAmp);
EXPORTS int eyemAutoCanny(EyemImage tpImage, float dSigma = 0.33);
EXPORTS int eyemEdgesPixel(EyemImage tpImage, double dThreshold, IntPtr *hObject, int *ipNum, EyemOcsDXY **hResults);
EXPORTS int eyemEdgesSubpixel(EyemImage tpImage, IntPtr *hObject, EyemOcsDXY **tpEdges, int iFilter, int iLow, int iHigh);
EXPORTS int eyemSkeleton(EyemImage tpImage, EyemImage &skeleton);
EXPORTS int eyemSobelAmp(EyemImage tpImage, EyemImage &ImaAmp);
EXPORTS int eyemAutoCanny(EyemImage tpImage, float dSigma = 0.33);
#ifdef __cplusplus
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
// 模板匹配(eyemMatchShapes.cpp)
//
#ifdef __cplusplus
extern "C" {
#endif
// 函数接口
EXPORTS int eyemMakeShapeModel(EyemImage tpImage, double dContrast, double dMinContrast, int iApertureSize = 3, bool bL2gradient = false);
EXPORTS int eyemFindShapeModel(EyemImage tpImage, int iNumLevels, double dAngleStart, double dAngleExtent, double dAngleStep, double dMinContrast, double dContrast, double dGreediness, double dMinScore, bool bOptimization = true);
#ifdef __cplusplus
}
......
#include "eyemMatchShapes.h"
shape_based_matching::~shape_based_matching(void) {}
shape_based_matching::~shape_based_matching(void)
int shape_based_matching::create_shape_model(cv::Mat tpTemplate, double maxContrast, double minContrast, double apertureSize, bool L2gradient)
{
delete[] resultPoints;
delete[] edgeMagnitude;
delete[] edgeDerivativeX;
delete[] edgeDerivativeY;
}
int shape_based_matching::create_shape_model(cv::Mat tpTemplate, double maxContrast, double minContrast)
{
cv::Mat gx;
cv::Mat gy;
cv::Mat nmsEdges;
cv::Size Ssize;
cv::Mat src(tpTemplate); //Above step replicated
// set width and height
Ssize.width = src.cols; //src->width;
Ssize.height = src.rows; //src->height;
modelHeight = src.rows; //src->height; //Save Template height
modelWidth = src.cols; //src->width; //Save Template width
noOfCordinates = 0; //initialize
resultPoints = new cv::Point[modelWidth * modelHeight]; //Allocate memory for coorinates of selected points in template image
edgeMagnitude = new double[modelWidth * modelHeight]; //Allocate memory for edge magnitude for selected points
edgeDerivativeX = new double[modelWidth * modelHeight]; //Allocate memory for edge X derivative for selected points
edgeDerivativeY = new double[modelWidth * modelHeight]; ////Allocate memory for edge Y derivative for selected points
// Calculate gradient of Template
gx = cv::Mat(Ssize.height, Ssize.width, CV_16SC1); //create Matrix to store X derivative
gy = cv::Mat(Ssize.height, Ssize.width, CV_16SC1); //create Matrix to store Y derivative
int incn = tpTemplate.channels();
if (incn != 1) {
cv::cvtColor(tpTemplate, tpTemplate, cv::COLOR_BGR2GRAY);
}
//获取边缘
cv::Mat edges;
cv::Canny(tpTemplate, edges, minContrast, maxContrast, (int)apertureSize, L2gradient);
auto contours = std::vector<std::vector<cv::Point>>();
cv::findContours(edges, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
Sobel(src, gx, CV_16S, 1, 0, 3); //gradient in X direction
Sobel(src, gy, CV_16S, 0, 1, 3); //gradient in Y direction
//计算偏导
cv::Mat gx, gy;
cv::Sobel(tpTemplate, gx, CV_64F, 1, 0, 3);
cv::Sobel(tpTemplate, gy, CV_64F, 0, 1, 3);
std::cout << "Sobel Done" << std::endl;
//计算梯度以及方向
cv::Mat magnitude, direction;
cv::cartToPolar(gx, gy, magnitude, direction);
nmsEdges = cv::Mat(Ssize.height, Ssize.width, CV_32F); //create Matrix to store Final nmsEdges
const short* _sdx;
const short* _sdy;
double fdx, fdy;
double MagG, DirG;
double MaxGradient = -99999.99;
double direction;
int *orients = new int[Ssize.height * Ssize.width];
// count variable;
int count = 0,
i,
j;
double **magMat;
create_double_matrix(magMat, Ssize);
std::cout << "Create Double Mat Done" << std::endl;
for (i = 1; i < Ssize.height - 1; i++)
auto sum = cv::Point2d(0, 0);
for (int i = 0; i < contours.size(); i++)
{
for (j = 1; j < Ssize.width - 1; j++)
for (int j = 0; j < contours[i].size(); j++)
{
fdx = gx.at<short>(i, j);
fdy = gy.at<short>(i, j);
MagG = sqrt((float)(fdx * fdx) + (float)(fdy * fdy)); //Magnitude = Sqrt(gx^2 +gy^2)
direction = atan2f((float)fdy, (float)fdx);//cvFastArctan((float)fdy,(float)fdx); //Direction = invtan (Gy / Gx)
magMat[i][j] = MagG;
if (MagG > MaxGradient)
MaxGradient = MagG; // get maximum gradient value for normalizing.
// get closest angle from 0, 45, 90, 135 set
if ((direction > 0 && direction < 22.5) || (direction > 157.5 && direction < 202.5) || (direction > 337.5 && direction < 360))
direction = 0;
else if ((direction > 22.5 && direction < 67.5) || (direction > 202.5 && direction < 247.5))
direction = 45;
else if ((direction > 67.5 && direction < 112.5) || (direction > 247.5 && direction < 292.5))
direction = 90;
else if ((direction > 112.5 && direction < 157.5) || (direction > 292.5 && direction < 337.5))
direction = 135;
else
direction = 0;
orients[count] = (int)direction;
count++;
auto cur = contours[i][j];
auto fdx = gx.ptr<double>(cur.y)[cur.x];
auto fdy = gy.ptr<double>(cur.y)[cur.x];
auto der = cv::Point2d(fdx, fdy);
auto mag = magnitude.ptr<double>(cur.y)[cur.x];
auto dir = direction.ptr<double>(cur.y)[cur.x];
results.push_back(PointInfo(cur, der, mag, dir));
sum.x += cur.x; sum.y += cur.y;
}
}
std::cout << "Ist fdx fdy Done" << std::endl;
count = 0; // init count
// non maximum suppression
double leftPixel, rightPixel;
for (i = 1; i < Ssize.height - 1; i++)
{
for (j = 1; j < Ssize.width - 1; j++)
{
switch (orients[count])
{
case 0:
leftPixel = magMat[i][j - 1];
rightPixel = magMat[i][j + 1];
break;
case 45:
leftPixel = magMat[i - 1][j + 1];
rightPixel = magMat[i + 1][j - 1];
break;
case 90:
leftPixel = magMat[i - 1][j];
rightPixel = magMat[i + 1][j];
break;
case 135:
leftPixel = magMat[i - 1][j - 1];
rightPixel = magMat[i + 1][j + 1];
break;
}
// compare current pixels value with adjacent pixels
if ((magMat[i][j] < leftPixel) || (magMat[i][j] < rightPixel))
nmsEdges.at<float>(i, j) = 0.0f;//(nmsEdges->data.ptr + nmsEdges->step*i)[j]=0;
else
nmsEdges.at<float>(i, j) = (uchar)(magMat[i][j] / MaxGradient * 255);//(nmsEdges->data.ptr + nmsEdges->step*i)[j]=(uchar)(magMat[i][j]/MaxGradient*255);
count++;
}
//模板尺寸
templSize = cv::Size(tpTemplate.cols, tpTemplate.rows);
//中心
auto Center = cv::Point2d(sum.x / results.size(), sum.y / results.size());
//更新位置
for (auto&item : results) {
item.update(Center);
}
std::cout << "Non max Done" << std::endl;
int RSum = 0, CSum = 0;
int curX, curY;
int flag = 1;
//
cv::Mat cc;
cv::cvtColor(tpTemplate, cc, cv::COLOR_GRAY2BGR);
//Hysterisis threshold
for (i = 1; i < Ssize.height - 1; i++)
{
for (j = 1; j < Ssize.width; j++)
{
//_sdx = (short*)(gx->data.ptr + gx->step*i);
//_sdy = (short*)(gy->data.ptr + gy->step*i);
//fdx = _sdx[j]; fdy = _sdy[j];
//std::cout << gx.elemSize1();
fdx = gx.at<short>(i, j);
fdy = gy.at<short>(i, j);
MagG = sqrt(fdx * fdx + fdy * fdy); //Magnitude = Sqrt(gx^2 +gy^2)
DirG = atan2f((float)fdy, (float)fdx); //cvFastArctan((float)fdy, (float)fdx); //Direction = tan(y/x)
return FUNC_OK;
}
////((uchar*)(imgGDir->imageData + imgGDir->widthStep*i))[j]= MagG;
flag = 1;
double val = nmsEdges.at<float>(i, j);
//std::cout << "nmsEdge float Done" << std::endl;
//if(((double)((nmsEdges->data.ptr + nmsEdges->step*i))[j]) < maxContrast)
if (val < maxContrast)
double shape_based_matching::find_shape_model(cv::Mat tpImage, double minScore, double greediness, cv::Point& resultPoint)
{
int incn = tpImage.channels();
if (incn != 1) {
cv::cvtColor(tpImage, tpImage, cv::COLOR_BGR2GRAY);
}
//尺寸信息
const int X = tpImage.cols, Y = tpImage.rows;
//用于显示
cv::Mat showMat;
cv::cvtColor(tpImage, showMat, cv::COLOR_GRAY2BGR);
//计算偏导
cv::Mat gx, gy;
cv::Sobel(tpImage, gx, CV_64F, 1, 0, 3);
cv::Sobel(tpImage, gy, CV_64F, 0, 1, 3);
//计算梯度以及方向
cv::Mat magnitude, direction;
cv::cartToPolar(gx, gy, magnitude, direction);
cv::Mat scoreMap(cv::Size(tpImage.cols, tpImage.rows), CV_64FC1, cv::Scalar(0));
//基于ncc匹配
long noOfCordinates = static_cast<int>(results.size());
double normMinScore = minScore / noOfCordinates;
double normGreediness = (1 - greediness*minScore) / ((1.0 - greediness) / noOfCordinates);
double partialScore = .0, resultScore = .0;
for (int i = 0; i < tpImage.rows; i++) {
for (int j = 0; j < tpImage.cols; j++) {
double partialSum = .0;
for (int m = 0; m < noOfCordinates; m++)
{
//if(((double)((nmsEdges->data.ptr + nmsEdges->step*i))[j])< minContrast)
if (val < minContrast)
{
//(nmsEdges->data.ptr + nmsEdges->step*i)[j] = 0;
nmsEdges.at<float>(i, j) = 0;
flag = 0; // remove from edge
////((uchar*)(imgGDir->imageData + imgGDir->widthStep*i))[j]=0;
}
else
{
if ((nmsEdges.at<float>(i - 1, j - 1) < maxContrast) &&
(nmsEdges.at<float>(i - 1, j) < maxContrast) &&
(nmsEdges.at<float>(i - 1, j + 1) < maxContrast) &&
(nmsEdges.at<float>(i, j - 1) < maxContrast) &&
(nmsEdges.at<float>(i, j + 1) < maxContrast) &&
(nmsEdges.at<float>(i + 1, j - 1) < maxContrast) &&
(nmsEdges.at<float>(i + 1, j) < maxContrast) &&
(nmsEdges.at<float>(i + 1, j + 1) < maxContrast)
)
{
nmsEdges.at<float>(i, j) = 0;
flag = 0;
}
}
auto item = results[m];
auto curX = (int)(j + item.Offset.x);
auto curY = (int)(i + item.Offset.y);
auto iTx = item.Derivative.x;
auto iTy = item.Derivative.y;
if (curX < 0 || curY < 0 || curY > tpImage.rows - 1 || curX > tpImage.cols - 1)
continue;
}
auto iSx = gx.ptr<double>(curY)[curX];
auto iSy = gy.ptr<double>(curY)[curX];
// save selected edge information
curX = i; curY = j;
if (flag != 0)
{
if (fdx != 0 || fdy != 0)
if ((iSx != 0 || iSy != 0) && (iTx != 0 || iTy != 0))
{
// Row sum and column sum for center of gravity
RSum = RSum + curX;
CSum = CSum + curY;
resultPoints[noOfCordinates].x = curX;
resultPoints[noOfCordinates].y = curY;
edgeDerivativeX[noOfCordinates] = fdx;
edgeDerivativeY[noOfCordinates] = fdy;
auto mag = magnitude.ptr<double>(curY)[curX];
auto matGradMag = (mag == 0) ? 0 : 1.0 / mag;
partialSum += ((iSx * iTx) + (iSy * iTy)) * (item.Magnitude * matGradMag);
//handle divide by zero
if (MagG != 0)
edgeMagnitude[noOfCordinates] = 1 / MagG; // gradient magnitude
else
edgeMagnitude[noOfCordinates] = 0;
auto sumOfCoords = m + 1;
partialScore = partialSum / sumOfCoords;
noOfCordinates++;
if (partialScore < MIN((minScore - 1) + normGreediness * sumOfCoords, normMinScore * sumOfCoords))
break;
}
}
scoreMap.ptr<double>(i)[j] = partialScore;
}
}
centerOfGravity.x = RSum / noOfCordinates; // center of gravity
centerOfGravity.y = CSum / noOfCordinates; // center of gravity
// change coordinates to reflect center of gravity
for (int m = 0; m < noOfCordinates; m++)
//归一化
cv::normalize(scoreMap, scoreMap, 1.0, 0, cv::NORM_MINMAX);
//计算结果非极大值抑制处理
std::vector<int> indices;
std::vector<cv::Rect> bboxes; std::vector<float> scoreIndex;
for (int y = 0; y < Y; y++)
{
int temp;
//cc.at<cv::Vec3b>(resultPoints[m].x, resultPoints[m].y) = cv::Vec3b(0, 0, 255);
temp = resultPoints[m].x;
resultPoints[m].x = temp - centerOfGravity.x;
temp = resultPoints[m].y;
resultPoints[m].y = temp - centerOfGravity.y;
for (int x = 0; x < X; x++)
{
if (scoreMap.ptr<double>(y)[x]>minScore) {
bboxes.push_back(cv::Rect(x - templSize.width / 2, y - templSize.height / 2, templSize.width, templSize.height));
scoreIndex.push_back((float)scoreMap.ptr<double>(y)[x]);
}
}
}
// free alocated memories
delete[] orients;
////cvReleaseImage(&imgGDir);
gx.release();
gy.release();
nmsEdges.release();
cv::dnn::NMSBoxes(bboxes, scoreIndex, (float)minScore, 0.25f, indices);
release_double_matrix(magMat, Ssize.height);
for (int i = 0; i < indices.size(); i++) {
resultPoint = (bboxes[indices[i]].tl() + bboxes[indices[i]].br()) / 2;
//画图显示
auto contours = std::vector<cv::Point>();
for (int i = 0; i < results.size(); i++)
{
contours.push_back(results[i].Offset + cv::Point2d(resultPoint));
}
draw_match_shapes(showMat, resultPoint, cv::Scalar(151, 243, 121), 1);
}
modelDefined = true;
return FUNC_OK;
cv::imwrite("result.png", showMat);
return 0;
}
double shape_based_matching::find_shape_model(cv::Mat tpImage, double minScore, double greediness, cv::Point* resultPoint)
void shape_based_matching::draw_match_shapes(cv::Mat &showMat, cv::Point cog, cv::Scalar color, int linew)
{
cv::Mat Sdx, Sdy;
double resultScore = 0;
double partialSum = 0;
double sumOfCoords = 0;
double partialScore;
const short* _Sdx;
const short* _Sdy;
int i, j, m; // count variables
double iTx, iTy, iSx, iSy;
double gradMag;
int curX, curY;
double **matGradMag; //Gradient magnitude matrix
cv::Mat src(tpImage);
// source image size
cv::Size Ssize;
Ssize.width = src.cols;
Ssize.height = src.rows;
create_double_matrix(matGradMag, Ssize); // create image to save gradient magnitude values
Sdx = cv::Mat(Ssize.height, Ssize.width, CV_16SC1); // X derivatives
Sdy = cv::Mat(Ssize.height, Ssize.width, CV_16SC1); // y derivatives
Sobel(src, Sdx, CV_16S, 1, 0, 3); // find X derivatives
Sobel(src, Sdy, CV_16S, 0, 1, 3); // find Y derivatives
// stoping criterias to search for model
double normMinScore = minScore / noOfCordinates; // precompute minumum score
double normGreediness = ((1 - greediness * minScore) / (1 - greediness)) / noOfCordinates; // precompute greedniness
for (i = 0; i < Ssize.height; i++)
//绘图显示
cv::circle(showMat, cog, 2, cv::Scalar(0, 0, 255), -1);
auto contours = std::vector<cv::Point>();
for (int i = 0; i < results.size(); i++)
{
for (j = 0; j < Ssize.width; j++)
{
iSx = Sdx.at<short>(i, j);
iSy = Sdy.at<short>(i, j);
gradMag = sqrt((iSx * iSx) + (iSy * iSy)); //Magnitude = Sqrt(dx^2 +dy^2)
if (gradMag != 0) // hande divide by zero
matGradMag[i][j] = 1 / gradMag; // 1/Sqrt(dx^2 +dy^2)
else
matGradMag[i][j] = 0;
}
contours.push_back(results[i].Offset + cv::Point2d(cog));
}
for (i = 0; i < Ssize.height; i++)
{
for (j = 0; j < Ssize.width; j++)
{
partialSum = 0; // initilize partialSum measure
for (m = 0; m < noOfCordinates; m++)
{
curX = i + resultPoints[m].x; // template X coordinate
curY = j + resultPoints[m].y; // template Y coordinate
iTx = edgeDerivativeX[m]; // template X derivative
iTy = edgeDerivativeY[m]; // template Y derivative
if (curX < 0 || curY < 0 || curX > Ssize.height - 1 || curY > Ssize.width - 1)
continue;
iSx = Sdx.at<short>(curX, curY); //CHECK IF curX AND curY NEED TO BE SWITCHED
iSy = Sdy.at<short>(curX, curY);
if ((iSx != 0 || iSy != 0) && (iTx != 0 || iTy != 0))
{
//partial Sum = Sum of(((Source X derivative* Template X drivative) + Source Y derivative * Template Y derivative)) / Edge magnitude of(Template)* edge magnitude of(Source))
partialSum = partialSum + ((iSx * iTx) + (iSy * iTy)) * (edgeMagnitude[m] * matGradMag[curX][curY]);
}
sumOfCoords = m + 1;
partialScore = partialSum / sumOfCoords;
// check termination criteria
// if partial score score is less than the score than needed to make the required score at that position
// break serching at that coordinate.
if (partialScore < (MIN((minScore - 1) + normGreediness * sumOfCoords, normMinScore * sumOfCoords)))
break;
}
if (partialScore > resultScore)
{
std::cout << "Partial Score is :" << partialScore << std::endl;
resultScore = partialScore; // Match score
resultPoint->x = i; // result coordinate X
resultPoint->y = j; // result coordinate Y
std::cout << "Result Point is :" << resultPoint->x << resultPoint->y << std::endl;
}
}
for (auto&point : contours) {
showMat.at<cv::Vec3b>(point) = cv::Vec3b((uchar)color[0], (uchar)color[1], (uchar)color[2]);
}
// free used resources and return score
release_double_matrix(matGradMag, Ssize.height);
Sdx.release();
Sdy.release();
return resultScore;
}
void shape_based_matching::create_double_matrix(double** &matrix, cv::Size size) {
matrix = new double*[size.height];
for (int iInd = 0; iInd < size.height; iInd++)
matrix[iInd] = new double[size.width];
}
int eyemMakeShapeModel(EyemImage tpImage, double dContrast, double dMinContrast, int iApertureSize, bool bL2gradient)
{
CV_Assert(NULL != tpImage.vpImage);
cv::Mat image = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
void shape_based_matching::release_double_matrix(double** &matrix, int size) {
for (int i = 0; i < size; i++)
delete[] matrix[i];
if (image.empty())
return FUNC_IMAGE_NOT_EXIST;
//创建模板
sbm.create_shape_model(image, dContrast, dMinContrast, iApertureSize, bL2gradient);
return FUNC_OK;
}
void shape_based_matching::draw_match_shapes(cv::Mat showMat, cv::Point cog, cv::Scalar color, int linew)
int eyemFindShapeModel(EyemImage tpImage, int iNumLevels, double dAngleStart, double dAngleExtent, double dAngleStep, double dMinContrast, double dContrast, double dGreediness, double dMinScore, bool bOptimization)
{
cv::Point point;
point.y = cog.x;
point.x = cog.y;
for (int i = 0; i < noOfCordinates; i++)
{
point.y = resultPoints[i].x + cog.x;
point.x = resultPoints[i].y + cog.y;
line(showMat, point, point, color, linew);
}
}
CV_Assert(NULL != tpImage.vpImage);
void shape_based_matching::draw_match_shapes(cv::Mat showMat, cv::Scalar color, int linew)
{
cv::Point point;
for (int i = 0; i < noOfCordinates; i++)
{
point.y = resultPoints[i].x + centerOfGravity.x;
point.x = resultPoints[i].y + centerOfGravity.y;
line(showMat, point, point, color, linew);
}
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;
//匹配模板
cv::Point result;
sbm.find_shape_model(image, dMinScore, dGreediness, result);
return FUNC_OK;
}
\ No newline at end of file
......@@ -6,7 +6,6 @@
#define __EYEM_MATCHSHAPES_H
#include "eyemLib.h"
#include <algorithm>
class shape_based_matching
{
......@@ -14,29 +13,35 @@ public:
shape_based_matching() {};
~shape_based_matching(void);
int create_shape_model(cv::Mat tpTemplate, double maxContrast, double minContrast);
int create_shape_model(cv::Mat tpTemplate, double maxContrast, double minContrast, double apertureSize = 3, bool L2gradient = false);
double find_shape_model(cv::Mat tpImage, double minScore, double greediness, cv::Point* resultPoint);
double find_shape_model(cv::Mat tpImage, double minScore, double greediness, cv::Point& resultPoint);
void draw_match_shapes(cv::Mat, cv::Point, cv::Scalar, int);
void draw_match_shapes(cv::Mat, cv::Scalar, int);
void draw_match_shapes(cv::Mat&, cv::Point, cv::Scalar, int);
private:
int noOfCordinates;
cv::Point* resultPoints;
int modelHeight;
int modelWidth;
double* edgeMagnitude;
double* edgeDerivativeX;
double* edgeDerivativeY;
cv::Point centerOfGravity;
bool modelDefined;
void create_double_matrix(double** &matrix, cv::Size size);
void release_double_matrix(double** &matrix, int size);
struct PointInfo
{
cv::Point Point;
cv::Point2d Center;
cv::Point2d Offset;
cv::Point2d Derivative;
double Magnitude, Direction;
PointInfo() {}
PointInfo(cv::Point Point, cv::Point2d Derivative, double Magnitude, double Direction) :Point(Point), Derivative(Derivative), Magnitude(Magnitude), Direction(Direction) {}
void update(cv::Point2d Center)
{
this->Center = Center;
this->Offset = cv::Point2d((double)this->Point.x - Center.x, (double)this->Point.y - Center.y);
}
};
cv::Size templSize;
std::vector<PointInfo> results;
};
shape_based_matching sbm;
#endif/* __EYEM_MATCHSHAPES_H */
\ No newline at end of file
......@@ -7941,7 +7941,6 @@ int eyemMulFuncTool(EyemImage tpImage, EyemRect tpRoi, const char *funcName, dou
return FUNC_OK;
}
#include "eyemMatchShapes.h"
int eyemLibImpl(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpDstImg)
{
CV_Assert(NULL != tpImage.vpImage);
......@@ -7956,109 +7955,6 @@ int eyemLibImpl(EyemImage tpImage, EyemHSVModel tpHSVModel, EyemImage *tpDstImg)
(tpHSVModel.dpRangeUExt[0] + tpHSVModel.dpRangeUExt[1] + tpHSVModel.dpRangeUExt[2]) != 0) {
std::cout << "红色" << std::endl;
}
return FUNC_OK;
//shape_based_matching GM; // object to implent geometric matching
//int lowThreshold = 10; //deafult value
//int highThreashold = 100; //deafult value
//double minScore = 0.25; //deafult value
//double greediness = 0.8; //deafult value
//double total_time = 0;
//double score = 0;
//cv::Point result;
//cv::Mat templateImage = cv::imread("D://批量测试图像//template2.png", cv::IMREAD_GRAYSCALE);
//if (templateImage.data == NULL)
//{
// return 0;
//}
////Load Search Image
//cv::Mat searchImage = cv::imread("D://批量测试图像//rings_01.png", cv::IMREAD_GRAYSCALE);
//if (searchImage.data == NULL)
//{
// return 0;
//}
//lowThreshold = atoi("10");
//highThreashold = atoi("100");//get high threshold
//minScore = atof("0.25");
//greediness = atof("0.9");
//cv::Mat grayTemplateImg; //(templateImage.size(), CV_8U, 1);
//templateImage.copyTo(grayTemplateImg);
//if (GM.create_shape_model(grayTemplateImg, lowThreshold, highThreashold) != FUNC_OK)
//{
// std::cout << "ERROR: could not create model...";
// return 0;
//}
//else {
// cv::Mat cc;
// cv::cvtColor(templateImage, cc, cv::COLOR_GRAY2BGR);
//}
////测试用833
////测试用
//cv::Mat cc;
//cv::cvtColor(templateImage, cc, cv::COLOR_GRAY2BGR);
//for (int i = 0; i < 833; i++)
//{
// //cc.ptr<cv::Vec3b>(resultPoints)[resultPoints[i].y] = cv::Vec3b(0, 0, 255);
//}
////CvSize searchSize = cvSize(searchImage->width, searchImage->height);
//cv::Mat graySearchImg; //= cvCreateImage(searchSize, IPL_DEPTH_8U, 1);
// // Convert color image to gray image.
//searchImage.copyTo(graySearchImg);
//clock_t start_time1 = clock();
//score = GM.find_shape_model(graySearchImg, minScore, greediness, &result);
//clock_t finish_time1 = clock();
//total_time = ((double)finish_time1 - (double)start_time1) / CLOCKS_PER_SEC;
//cv::Mat rgb;
//if (score > minScore) // if score is atleast 0.4
//{
// std::cout << " Found at [" << result.x << ", " << result.y << "]\n Score = " << score << "\n Searching Time = " << total_time * 1000 << "ms";
// cvtColor(searchImage, rgb, cv::COLOR_GRAY2BGR);
// GM.draw_match_shapes(rgb, result, cv::Scalar(0, 255, 0), 1);
//}
//else
// std::cout << " Object Not found";
////////////////////////////////////
//std::cout << "\n ------------------------------------\n\n";
//std::cout << "\n Press any key to exit!";
////Display result
//cv::Mat dispTemplate;
//cvtColor(templateImage, dispTemplate, cv::COLOR_GRAY2BGR);
//GM.draw_match_shapes(dispTemplate, CV_RGB(255, 0, 0), 1);
//cv::namedWindow("Template", cv::WINDOW_AUTOSIZE);
//cv::imshow("Template", dispTemplate);
//cv::namedWindow("Search Image", cv::WINDOW_AUTOSIZE);
//imshow("Search Image", rgb);
//cv::waitKey(0);
//cv::destroyWindow("Search Image");
//cv::destroyWindow("Template");
//return 0;
#pragma region resize img
//const int minInputSize = 832;
......
......@@ -387,10 +387,16 @@ int eyemNonLocalMeansFilter(EyemImage tpImage, int iCMPSize, int iSearchSize, do
//mvs[2] = cv::imread("C:\\Users\\nzslw\\OneDrive\\程序\\VSProject\\eyemLib\\x64\\Debug\\Portada_paper_r.png", 0);
cv::Mat dest;
//cv::blur(image, dest, cv::Size(3, 3));
//cv::merge(mvs, dest);
nonLocalMeansFilter_SSE(image, dest, cv::Size(3, 3), cv::Size(5, 5), 21.0, -1, 0);
//for (int i = 0; i < 10; i++)
//{
//nonLocalMeansFilter_SSE(image, dest, cv::Size(3, 3), cv::Size(5, 5), 10.0, -1, 0);
//image = dest;
//}
cv::imwrite("Portada_paper5.png", dest);
//cv::imwrite("Portada_paper5.png", dest);
return FUNC_OK;
}
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!