Commit 5d868695 张士柳

1 个父辈 c28b0fea
......@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;
using System.IO;
namespace eyemLib_Sharp
{
......@@ -342,6 +343,14 @@ namespace eyemLib_Sharp
public double dVar; // 某种可能会使用的值
}
[StructLayout(LayoutKind.Sequential)]
public struct BboxContainer
{
//最多支持100个目标
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public EyemRect[] bboxes;
}
///////////////////////////////////////////////////////////////////////////////
// Orthogonal Coordinate System
......@@ -1020,6 +1029,25 @@ namespace eyemLib_Sharp
private static extern int eyemClp2dTangentPointToCircle(EyemOcsDXY tpPoint, EyemOcsDXYR tpCircle, ref EyemOcsDABC tpTangent1, ref EyemOcsDXY tpContact1, ref EyemOcsDABC tpTangent2, ref EyemOcsDXY tpContact2);
#endregion
#region 深度学习目标检测器
/// <summary>
/// 初始化检测器
/// </summary>
/// <param name="detectorConfigPath">配置文件</param>
/// <param name="detectorModelPath">模型文件</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemInitNNDetector(string detectorConfigPath, string detectorModelPath);
/// <summary>
/// 目标检测器
/// </summary>
/// <param name="tpImage">输入图像</param>
/// <returns></returns>
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
private static extern int eyemNNDetector(EyemImage tpImage, out int ipNum, ref BboxContainer container);
#endregion
#region 项目
//普通器件(仍采用旧的算法)
[DllImport("eyemLib.dll", CharSet = CharSet.None, CallingConvention = CallingConvention.Cdecl)]
......@@ -1356,6 +1384,14 @@ namespace eyemLib_Sharp
//eyemEdgesPixel(ucpImage, 15);
#endregion
#region Test NNDetector
//eyemInitNNDetector(".\\darknet\\detect-tiny-label.cfg", ".\\darknet\\detect-tiny-label.weights");
//int ipNum = 0;
//BboxContainer container = new BboxContainer();
//eyemNNDetector(image, out ipNum, ref container);
#endregion
EyemRect tpRoi = new EyemRect();
tpRoi.iXs = 200; tpRoi.iYs = 150;
......@@ -1700,6 +1736,44 @@ namespace eyemLib_Sharp
eyemImageFree(ref image);
}
#region 文件重新命名
public static void eyemRenameFile(string filePath)
{
List<string> fileNames = new List<string>();
getAllFiles(filePath, ref fileNames);
//批量重命名
for (int index = 0; index < fileNames.Count; index++)
{
string destFileNmae = "D://标签识别//" + index.ToString().PadLeft(5, '0') + ".png";
File.Move(fileNames[index], destFileNmae);
}
}
static void getAllFiles(string filePath, ref List<string> fileNames)
{
getDirectory(filePath, ref fileNames);
}
public static void getFileName(string path, ref List<string> fileNames)
{
DirectoryInfo root = new DirectoryInfo(path);
foreach (FileInfo f in root.GetFiles())
{
fileNames.Add(f.FullName);
}
}
public static void getDirectory(string path, ref List<string> fileNames)
{
getFileName(path, ref fileNames);
DirectoryInfo root = new DirectoryInfo(path);
foreach (DirectoryInfo d in root.GetDirectories())
{
getDirectory(d.FullName, ref fileNames);
}
}
#endregion
#region EyemImageBitmap相互转换
public static Bitmap eyemCvtToBitmap(EyemImage tpImage)
{
......
......@@ -16,6 +16,8 @@ namespace eyemLib_Sharp
di.Create();
}
//EyemLib.eyemRenameFile(@"D:\新建文件夹");
//初始化
EyemLib.Init();
......
......@@ -987,30 +987,24 @@ static double getThreshVal_Otsu_8u(const cv::Mat& _src)
int eyemBinThreshold(EyemImage tpSrcImg, int iLightDark, double dThresh, double dMaxVal, EyemImage *tpDstImg)
{
cv::Mat image = cv::Mat(tpSrcImg.iHeight, tpSrcImg.iWidth, MAKETYPE(tpSrcImg.iDepth, tpSrcImg.iChannels), tpSrcImg.vpImage).clone();
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
cv::Mat binary;
//执行二值化操作
cv::threshold(image, binary, dThresh, dMaxVal, iLightDark);
tpDstImg->iWidth = binary.cols; tpDstImg->iHeight = binary.rows; tpDstImg->iDepth = binary.depth(); tpDstImg->iChannels = binary.channels();
//输出结果图像
{
tpDstImg->iWidth = binary.cols; tpDstImg->iHeight = binary.rows; tpDstImg->iDepth = binary.depth(); tpDstImg->iChannels = binary.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);
//内存尺寸
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, binary.data, _Size);
//拷贝数据
memcpy(tpDstImg->vpImage, binary.data, _Size);
}
return FUNC_OK;
}
......@@ -1272,7 +1266,7 @@ int eyemBinClosing(EyemImage tpSrcImg, int iBinLevel, int iNum, EyemImage *tpDst
int eyemBinBlob(EyemImage tpImage, IntPtr *hObject, int iAreaThrs, EyemBinBlob **tpResult, int *ipNum, EyemImage *tpDstImg)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage);
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;
......
......@@ -126,13 +126,14 @@ void eyemClp2dAreaTriangle(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY
int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcsDXY tpPoint3, EyemOcsDXYR &tpCircle)
{
//计算系数
double sa[9], sb[3];
double sa[9], sb[3], sx[3];
cv::Mat a = cv::Mat(3, 3, CV_64F, sa), b = cv::Mat(3, 1, CV_64F, sb);
//系数矩阵A*X=B;
cv::Mat x = cv::Mat(3, 1, CV_64F);
cv::Mat x = cv::Mat(3, 1, CV_64F, sx);
std::memset(sa, 0, sizeof(sa));
std::memset(sb, 0, sizeof(sb));
std::memset(sx, 0, sizeof(sx));
sa[0] = -2.0*tpPoint1.dX, sa[1] = -2.0*tpPoint1.dY, sa[2] = 1.;
sa[3] = -2.0*tpPoint2.dX, sa[4] = -2.0*tpPoint2.dY, sa[5] = 1.;
......@@ -144,9 +145,9 @@ int eyemClp2dCircleThreePoints(EyemOcsDXY tpPoint1, EyemOcsDXY tpPoint2, EyemOcs
//solve
cv::solve(a, b, x, cv::DECOMP_SVD);
tpCircle.dX = x.ptr<double>(0)[0];
tpCircle.dY = x.ptr<double>(1)[0];
tpCircle.dR = sqrt(pow(x.ptr<double>(0)[0], 2) + pow(x.ptr<double>(1)[0], 2) - (x.ptr<double>(2)[0]));
tpCircle.dX = sx[0];
tpCircle.dY = sx[1];
tpCircle.dR = sqrt(pow(sx[0], 2) + pow(sx[1], 2) - (sx[2]));
return FUNC_OK;
}
......
#include "nnDetector.h"
#include "eyemCodeDetector.h"
#include "yoloWrapper.h"
#include "barcodeDetector.h"
class NNDetector::Impl {
class CodeDetector::Impl {
public:
Impl() {}
~Impl() {}
......@@ -26,11 +26,11 @@ public:
std::shared_ptr<BarcodeDetector> bardetector_;
};
NNDetector::NNDetector(const std::string & detector_config_path,
CodeDetector::CodeDetector(const std::string & detector_config_path,
const std::string & detector_model_path,
const std::string & super_resolution_prototxt_path,
const std::string & super_resolution_caffe_model_path) {
p = cv::makePtr<NNDetector::Impl>();
p = cv::makePtr<CodeDetector::Impl>();
if (!detector_config_path.empty() && !detector_model_path.empty()) {
p->detector_ = std::make_shared<YoloWrapper>();
p->detector_->init(detector_config_path, detector_model_path);
......@@ -42,7 +42,7 @@ NNDetector::NNDetector(const std::string & detector_config_path,
//TODO:初始化超分辨率图像模型
}
std::vector<std::string> NNDetector::detectAndDecode(cv::InputArray img, std::vector<cv::Rect> &points, std::vector<cv::Rect> &__points) {
std::vector<std::string> CodeDetector::detectAndDecode(cv::InputArray img, std::vector<cv::Rect> &points, std::vector<cv::Rect> &__points) {
CV_Assert(!img.empty());
if (img.cols() <= 20 || img.rows() <= 20) {
......@@ -78,11 +78,11 @@ std::vector<std::string> NNDetector::detectAndDecode(cv::InputArray img, std::ve
return results;
}
std::vector<cv::Rect> NNDetector::Impl::detect(const cv::Mat& img) {
std::vector<cv::Rect> CodeDetector::Impl::detect(const cv::Mat& img) {
return detector_->forward(img);
}
std::vector<std::string> NNDetector::Impl::decode(const cv::Mat& img, std::vector<cv::Rect>& bboxes, std::vector<cv::Rect>& points) {
std::vector<std::string> CodeDetector::Impl::decode(const cv::Mat& img, std::vector<cv::Rect>& bboxes, std::vector<cv::Rect>& points) {
if (bboxes.size() == 0) {
logger.t("__eyemDetectAndDecodeUseNN__detectAndDecode__decode__:未识别到二维码");
return std::vector<std::string>();
......@@ -138,7 +138,7 @@ std::vector<std::string> NNDetector::Impl::decode(const cv::Mat& img, std::vecto
return decode_results;
}
std::vector<std::string> NNDetector::detectAndDecodeBarcode(cv::InputArray img, cv::Mat &showMat, std::vector<cv::Point> &points) {
std::vector<std::string> CodeDetector::detectAndDecodeBarcode(cv::InputArray img, cv::Mat &showMat, std::vector<cv::Point> &points) {
CV_Assert(!img.empty());
......@@ -230,13 +230,13 @@ std::vector<std::string> NNDetector::detectAndDecodeBarcode(cv::InputArray img,
return results;
}
std::vector<float> NNDetector::Impl::getScaleList(const int width, const int height) {
std::vector<float> CodeDetector::Impl::getScaleList(const int width, const int height) {
if (width < 320 || height < 320) return{ 1.0, 2.0, 0.5 };
if (width < 640 && height < 640) return{ 1.0, 0.5 };
return{ 0.5, 1.0 };
}
cv::Mat NNDetector::Impl::processImageScale(const cv::Mat &src, float scale) {
cv::Mat CodeDetector::Impl::processImageScale(const cv::Mat &src, float scale) {
cv::Mat sr = src;
if (scale == 1.0) {
return sr;
......
#pragma once
//
// detectAndDecode2d¡¤±êÍ·
// eyemCodeDetector¡¤±êÍ·
//
#ifndef __NNDETECTOR_H
#define __NNDETECTOR_H
#ifndef __EYEMCODEDETECTOR_H
#define __EYEMCODEDETECTOR_H
#include "opencv2/core.hpp"
#include "libdecode.h"
......@@ -11,13 +11,13 @@
extern Logger logger;
class NNDetector {
class CodeDetector {
public:
NNDetector(const std::string& detector_config_path = "",
CodeDetector(const std::string& detector_config_path = "",
const std::string& detector_model_path = "",
const std::string& super_resolution_config_path = "",
const std::string& super_resolution_model_path = "");
NNDetector() {};
CodeDetector() {};
std::vector<std::string> detectAndDecode(cv::InputArray img,
std::vector<cv::Rect> &points = std::vector<cv::Rect>(), std::vector<cv::Rect> &allpoints = std::vector<cv::Rect>());
......@@ -30,5 +30,5 @@ protected:
class Impl;
cv::Ptr<Impl> p;
};
#endif/* __NNDETECTOR_H */
#endif/* __EYEMCODEDETECTOR_H */
......@@ -522,7 +522,7 @@ int eyemDetectAndDecodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *hObject,
logger.t("__eyemDetectAndDecodeUseNN__:开始识别并解码二维码");
//识别并解码
std::vector<cv::Rect> points; std::vector<cv::Rect> __points;
auto results = detector->detectAndDecode(image, points, __points);
auto results = pCodeDetector->detectAndDecode(image, points, __points);
#pragma region discard
//if (image.channels() == 1) {
......@@ -553,7 +553,7 @@ int eyemDetectAndDecodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *hObject,
// cv::putText(showMat, label, cv::Point(points[c].tl().x, points[c].tl().y - baseLine), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);
//}
/////<输出结果图像
////<输出结果图像
//{
// tpDstImg->iWidth = showMat.cols; tpDstImg->iHeight = showMat.rows; tpDstImg->iDepth = showMat.depth(); tpDstImg->iChannels = showMat.channels();
......@@ -623,7 +623,7 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
cv::Mat showMat = image.clone();
//识别并解码
std::vector<cv::Point> points;
auto results = detector->detectAndDecodeBarcode(image, showMat, points);
auto results = pCodeDetector->detectAndDecodeBarcode(image, showMat, points);
#pragma region discard
......@@ -638,7 +638,7 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
// cv::putText(showMat, label, cv::Point(points[c].x, points[c].y - baseLine), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);
//}
/////<输出结果图像
////<输出结果图像
//{
// tpDstImg->iWidth = showMat.cols; tpDstImg->iHeight = showMat.rows; tpDstImg->iDepth = showMat.depth(); tpDstImg->iChannels = showMat.channels();
......@@ -692,12 +692,10 @@ int eyemDetectAndDecodeBarcodeUseNN(EyemImage tpImage, EyemRect tpRoi, IntPtr *h
int eyemInitNNDataCodeModel(const char *detectorConfigPath, const char *detectorModelPath, const char *superResolutionConfigPath, const char *superResolutionModelPath)
{
try
{
detector = cv::makePtr<NNDetector>(detectorConfigPath, detectorModelPath, superResolutionConfigPath, superResolutionModelPath);
try {
pCodeDetector = cv::makePtr<CodeDetector>(detectorConfigPath, detectorModelPath, superResolutionConfigPath, superResolutionModelPath);
}
catch (const std::exception& e)
{
catch (const std::exception& e) {
std::cout << e.what() << std::endl;
return FUNC_CANNOT_CALC;
}
......
......@@ -13,11 +13,11 @@
#endif
#include "eyemLib.h"
#include "nnDetector.h"
#include "eyemCodeDetector.h"
std::mutex mtx;
cv::Ptr<NNDetector> detector;
cv::Ptr<CodeDetector> pCodeDetector;
extern Logger logger;
......
#include"eyemEdge.h"
void thinningIteration(cv::Mat& img, int iter)
int eyemEdgesPixel(EyemImage tpImage, double dThreshold)
{
CV_Assert(img.channels() == 1);
CV_Assert(img.depth() != sizeof(uchar));
CV_Assert(img.rows > 3 && img.cols > 3);
cv::Mat marker = cv::Mat::zeros(img.size(), CV_8UC1);
int nRows = img.rows;
int nCols = img.cols;
if (img.isContinuous()) {
nCols *= nRows;
nRows = 1;
}
int x, y;
uchar *pAbove;
uchar *pCurr;
uchar *pBelow;
uchar *nw, *no, *ne; // north (pAbove)
uchar *we, *me, *ea;
uchar *sw, *so, *se; // south (pBelow)
uchar *pDst;
// initialize row pointers
pAbove = NULL;
pCurr = img.ptr<uchar>(0);
pBelow = img.ptr<uchar>(1);
for (y = 1; y < img.rows - 1; ++y) {
// shift the rows up by one
pAbove = pCurr;
pCurr = pBelow;
pBelow = img.ptr<uchar>(y + 1);
pDst = marker.ptr<uchar>(y);
// initialize col pointers
no = &(pAbove[0]);
ne = &(pAbove[1]);
me = &(pCurr[0]);
ea = &(pCurr[1]);
so = &(pBelow[0]);
se = &(pBelow[1]);
for (x = 1; x < img.cols - 1; ++x) {
// shift col pointers left by one (scan left to right)
nw = no;
no = ne;
ne = &(pAbove[x + 1]);
we = me;
me = ea;
ea = &(pCurr[x + 1]);
sw = so;
so = se;
se = &(pBelow[x + 1]);
int A = (*no == 0 && *ne == 1) + (*ne == 0 && *ea == 1) +
(*ea == 0 && *se == 1) + (*se == 0 && *so == 1) +
(*so == 0 && *sw == 1) + (*sw == 0 && *we == 1) +
(*we == 0 && *nw == 1) + (*nw == 0 && *no == 1);
int B = *no + *ne + *ea + *se + *so + *sw + *we + *nw;
int m1 = iter == 0 ? (*no * *ea * *so) : (*no * *ea * *we);
int m2 = iter == 0 ? (*ea * *so * *we) : (*no * *so * *we);
if (A == 1 && (B >= 2 && B <= 6) && m1 == 0 && m2 == 0)
pDst[x] = 1;
}
}
img &= ~marker;
}
static void thinning(const cv::Mat& src, cv::Mat& dst)
{
dst = src.clone();
dst /= 255; // convert to binary image
cv::Mat prev = cv::Mat::zeros(dst.size(), CV_8UC1);
cv::Mat diff;
do {
thinningIteration(dst, 0);
thinningIteration(dst, 1);
cv::absdiff(dst, prev, diff);
dst.copyTo(prev);
} while (cv::countNonZero(diff) > 0);
dst *= 255;
}
int eyemEdgesPixel(EyemImage tpImage, double dThresh)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
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;
}
int X = image.cols, Y = image.rows;
uchar *upF = image.data;
/*计算偏导*/
double *dpFx = (double *)malloc(X*Y * sizeof(double));
double *dpFy = (double *)malloc(X*Y * sizeof(double));
......@@ -111,10 +16,8 @@ int eyemEdgesPixel(EyemImage tpImage, double dThresh)
double *dpMag = (double *)malloc(X*Y * sizeof(double));
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
{
for (int x = 1; x < X - 1; x++)
{
for (int y = range.start; y < range.end; y++) {
for (int x = 1; x < X - 1; x++) {
dpFx[(x)+(y)*X] = 0.5*((double)(upF[(x + 1) + (y)*X]) - (double)(upF[(x - 1) + (y)*X]));
dpFy[(x)+(y)*X] = 0.5*((double)(upF[(x)+(y + 1)*X]) - (double)(upF[(x)+(y - 1)*X]));
dpMag[(x)+(y)*X] = sqrt(dpFx[(x)+(y)*X] * dpFx[(x)+(y)*X] + dpFy[(x)+(y)*X] * dpFy[(x)+(y)*X]);
......@@ -128,43 +31,34 @@ int eyemEdgesPixel(EyemImage tpImage, double dThresh)
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
for (int x = 1; x < (X - 1); x++)
{
if (dpMag[(x)+(y)*X] > dThresh)
{
for (int x = 1; x < (X - 1); x++) {
if (dpMag[(x)+(y)*X] > dThreshold) {
//判断边缘
if (abs(dpFy[(x)+(y)*X]) >= abs(dpFx[(x)+(y)*X]) &&
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X]))
{
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X])) {
ucpLabel[(x)+(y)*X] = 255;//垂直边缘-2
}
else if (abs(dpFx[(x)+(y)*X]) > abs(dpFy[(x)+(y)*X]) &&
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X]))
{
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X])) {
ucpLabel[(x)+(y)*X] = 255;//水平边缘-1
}
}
}
});
//标记连通域
//标记连通域,根据不同连通域显示不同颜色
cv::Mat labels;
int ilabel = cv::connectedComponents(label, labels);
//绘制连通域
std::vector<cv::Vec3b> labelColor(ilabel);
for (int i = 0; i < ilabel; i++)
{
for (int i = 0; i < ilabel; i++) {
labelColor[i] = cv::Vec3b(rand() % 256, rand() % 256, rand() % 256);
}
cv::Mat labelImage;
cv::cvtColor(image, labelImage, cv::COLOR_GRAY2BGR);
for (int y = 1; y < Y - 1; y++)
{
for (int x = 1; x < X - 1; x++)
{
for (int y = 1; y < Y - 1; y++) {
for (int x = 1; x < X - 1; x++) {
int lb = labels.at<int>(y, x);
if (lb != 0)
{
if (lb != 0) {
labelImage.at<cv::Vec3b>(y, x) = labelColor[lb];
}
}
......@@ -179,16 +73,13 @@ int eyemEdgesPixel(EyemImage tpImage, double dThresh)
int eyemEdgesSubpixel(EyemImage tpImage, int iFilter, int iLow, int iHigh)
{
cv::Mat image(tpImage.iHeight, tpImage.iWidth, CV_8UC1, tpImage.vpImage);
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;
}
int X = image.cols, Y = image.rows;
uchar *upF = image.data;
/*计算偏导*/
double *dpFx = (double *)malloc(X*Y * sizeof(double));
double *dpFy = (double *)malloc(X*Y * sizeof(double));
......@@ -196,10 +87,8 @@ int eyemEdgesSubpixel(EyemImage tpImage, int iFilter, int iLow, int iHigh)
double *dpMag = (double *)malloc(X*Y * sizeof(double));
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
{
for (int x = 1; x < X - 1; x++)
{
for (int y = range.start; y < range.end; y++) {
for (int x = 1; x < X - 1; x++) {
dpFx[(x)+(y)*X] = 0.5*((double)(upF[(x + 1) + (y)*X]) - (double)(upF[(x - 1) + (y)*X]));
dpFy[(x)+(y)*X] = 0.5*((double)(upF[(x)+(y + 1)*X]) - (double)(upF[(x)+(y - 1)*X]));
dpMag[(x)+(y)*X] = sqrt(dpFx[(x)+(y)*X] * dpFx[(x)+(y)*X] + dpFy[(x)+(y)*X] * dpFy[(x)+(y)*X]);
......@@ -213,81 +102,55 @@ int eyemEdgesSubpixel(EyemImage tpImage, int iFilter, int iLow, int iHigh)
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
for (int x = 1; x < (X - 1); x++)
{
if (dpMag[(x)+(y)*X] > 25)
{
for (int x = 1; x < (X - 1); x++) {
if (dpMag[(x)+(y)*X] > 25) {
//判断边缘
if (abs(dpFy[(x)+(y)*X]) >= abs(dpFx[(x)+(y)*X]) &&
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X]))
{
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X])) {
ucpLabel[(x)+(y)*X] = 255;//垂直边缘-2
}
else if (abs(dpFx[(x)+(y)*X]) > abs(dpFy[(x)+(y)*X]) &&
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X]))
{
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X])) {
ucpLabel[(x)+(y)*X] = 255;//水平边缘-1
}
}
}
});
cv::Mat labels;
cv::connectedComponents(label, labels);
//所有边缘
EyemOcsDXY temp;
EyemOcsDXY edge;
std::vector<EyemOcsDXY> edges;
cv::parallel_for_(cv::Range(1, Y - 1), [&](const cv::Range& range) -> void {
for (int y = range.start; y < range.end; y++)
for (int x = 1; x < (X - 1); x++)
{
if (ucpLabel[(x)+(y)*X] != 0)
{
for (int x = 1; x < (X - 1); x++) {
if (ucpLabel[(x)+(y)*X] != 0) {
//判断边缘
if (abs(dpFy[(x)+(y)*X]) >= abs(dpFx[(x)+(y)*X]) &&
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X]))
{
abs(dpFy[(x)+(y)*X]) >= abs(dpFy[(x)+(y - 1)*X]) && abs(dpFy[(x)+(y)*X]) > abs(dpFy[(x)+(y + 1)*X])) {
//垂直边缘
double a, b, c, u;
a = dpMag[(x)+(y - 1)*X];
b = dpMag[(x)+(y)*X];
c = dpMag[(x)+(y + 1)*X];
u = 0.5*(a - c) / (a - b - b + c);
temp.dX = (float)x + 0.5f;
temp.dY = (float)y + 0.5f + (float)u;
edges.push_back(temp);
edge.dX = (float)x + 0.5f;
edge.dY = (float)y + 0.5f + (float)u;
edges.push_back(edge);
}
else if (abs(dpFx[(x)+(y)*X]) > abs(dpFy[(x)+(y)*X]) &&
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X]))
{
abs(dpFx[(x)+(y)*X]) >= abs(dpFx[(x - 1) + (y)*X]) && abs(dpFx[(x)+(y)*X]) > abs(dpFx[(x + 1) + (y)*X])) {
//水平边缘
double a, b, c, u;
a = dpMag[(x - 1) + (y)*X];
b = dpMag[(x)+(y)*X];
c = dpMag[(x + 1) + (y)*X];
u = 0.5*(a - c) / (a - b - b + c);
temp.dX = (float)x + 0.5f + (float)u;
temp.dY = (float)y + 0.5f;
edges.push_back(temp);
edge.dX = (float)x + 0.5f + (float)u;
edge.dY = (float)y + 0.5f;
edges.push_back(edge);
}
}
}
});
//cv::RNG rng;
//cv::Mat show;
//cv::cvtColor(image.clone(), show, cv::COLOR_GRAY2BGR);
//int cnt = 0;
//for (int i = 0; i < contours.size(); i++)
//{
// cv::Vec3b color = cv::Vec3b(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
// for (int j = 0; j < contours[i].size(); j++)
// {
// cnt++;
// show.at<cv::Vec3b>(contours[i][j]) = color;
// }
// //drawContours(show, contours, i, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), 3);
//}
//释放资源
free((void *)ucpLabel);
free((void *)dpFx);
......@@ -319,7 +182,6 @@ int eyemSkeleton(EyemImage tpImage, cv::Mat &skeleton)
if (image.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
thinning(image, skeleton);
return FUNC_OK;
}
......
......@@ -168,8 +168,7 @@ static void fitLine2D_wods(int iPtnNum, const EyemOcsDXY *taPoints, float *weigh
std::memset(sa, 0, sizeof(sa));
std::memset(sb, 0, sizeof(sb));
std::memset(sx, 0, sizeof(sx));
for (int i = 0; i < iPtnNum; i++)
{
for (int i = 0; i < iPtnNum; i++) {
sa[0] += weights[i];
sa[1] += weights[i] * taPoints[i].dX;
sa[3] += weights[i] * taPoints[i].dX*taPoints[i].dX;
......@@ -185,7 +184,6 @@ static void fitLine2D_wods(int iPtnNum, const EyemOcsDXY *taPoints, float *weigh
//solve ax=b
bool solved = cv::solve(a, b, x, cv::DECOMP_SVD);
if (!solved)
return;
......@@ -247,8 +245,7 @@ int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double d
break;
}
for (int it = 0; it < 50; it++)
{
for (int n = 0; n < 50; n++) {
float sum_dist = .0, sum_w = .0;
/*calculate parameter*/
......@@ -260,8 +257,7 @@ int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double d
cv::AutoBuffer<float> dist(iPtnNum);
/*calculate distance*/
for (int k = 0; k < iPtnNum; k++)
{
for (int k = 0; k < iPtnNum; k++) {
dist[k] = fabs(nx*(float)taPoints[k].dX + ny*(float)taPoints[k].dY - (nx*px + ny*py)) / sqrt(nx*nx + ny*ny);
sum_dist += dist[k];
}
......@@ -290,10 +286,8 @@ int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double d
static void fitLine2D_wods(int iPtnNum, const EyemOcsDXY2D *taPoints, EyemOcsDABC &tpLine)
{
std::vector<cv::Point2f> points;
for (int i = 0; i < iPtnNum; i++)
{
if (taPoints[i].bValid)
{
for (int i = 0; i < iPtnNum; i++) {
if (taPoints[i].bValid) {
points.push_back(cv::Point2f((float)taPoints[i].dX, (float)taPoints[i].dY));
}
}
......@@ -316,8 +310,7 @@ int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &
}
auto taPoints = std::vector<EyemOcsDXY2D>(iPtnNum);
for (int i = 0; i < iPtnNum; i++)
{
for (int i = 0; i < iPtnNum; i++) {
taPoints[i].bValid = true;
taPoints[i].dX = taPoint[i].dX;
taPoints[i].dY = taPoint[i].dY;
......@@ -328,29 +321,24 @@ int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &
//Initialize the parameters with Robust method
fitLine2D_wods(iPtnNum, &taPoints[0], tpLine);
for (int it = 0; it < 50; it++)
{
for (int n = 0; n < 50; n++) {
double sr = 0.0, r = 0.0;
/* calculate distances */
for (int i = 0; i < iPtnNum; i++)
{
for (int i = 0; i < iPtnNum; i++) {
taPoints[i].bValid = true;
taPoints[i].dE = std::pow(calcDist2D(taPoints[i], tpLine.dA, tpLine.dB, tpLine.dC), 2);
}
//sort by dE
std::sort(taPoints.begin(), taPoints.end(), std::less<EyemOcsDXY2D>());
for (int i = (iPtnNum - numToIgnore); i < iPtnNum; i++)
{
for (int i = (iPtnNum - numToIgnore); i < iPtnNum; i++) {
taPoints[i].bValid = false;
}
/* Run again... */
fitLine2D_wods(iPtnNum, &taPoints[0], tpLine);
for (int i = 0; i < iPtnNum; i++)
{
if (taPoints[i].bValid)
{
for (int i = 0; i < iPtnNum; i++) {
if (taPoints[i].bValid) {
r = std::pow(calcDist2D(taPoints[i], tpLine.dA, tpLine.dB, tpLine.dC), 2);
sr += r;
}
......@@ -361,7 +349,6 @@ int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &
if (std::abs(err - min_err) < EPS)
break;
min_err = err;
}
return FUNC_OK;
......@@ -372,10 +359,8 @@ static void fitCircle2D_wods(int iPtnNum, const EyemOcsDXY2D *taPoints, EyemOcsD
return;
}
std::vector<cv::Point2d> points;
for (int i = 0; i < iPtnNum; i++)
{
if (taPoints[i].bValid)
{
for (int i = 0; i < iPtnNum; i++) {
if (taPoints[i].bValid) {
points.push_back(cv::Point2d(taPoints[i].dX, taPoints[i].dY));
}
}
......@@ -386,8 +371,7 @@ static void fitCircle2D_wods(int iPtnNum, const EyemOcsDXY2D *taPoints, EyemOcsD
cv::Mat x = cv::Mat(3, 1, CV_64F);
memset(sa, 0, sizeof(sa));
memset(sb, 0, sizeof(sb));
for (size_t i = 0; i < points.size(); i++)
{
for (int i = 0; i < points.size(); i++) {
sa[0] += (double)points[i].x;
sa[1] += (double)points[i].y;
sa[2] += 1.0;
......@@ -425,25 +409,21 @@ int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, double &RMS
double rms = .0;
fitCircle2D_wods(iPtnNum, &taPoints[0], tpCircle);
//迭代计算
for (int it = 0; it < 50; it++)
{
for (int n = 0; n < 50; n++) {
double sr = 0.0, r = 0.0;
for (int i = 0; i < iPtnNum; i++)
{
for (int i = 0; i < iPtnNum; i++) {
taPoints[i].bValid = true;
taPoints[i].dE = std::pow(calcDist(taPoints[i], tpCircle) - tpCircle.dR, 2);
}
//排序
std::sort(taPoints.begin(), taPoints.end(), std::less<EyemOcsDXY2D>());
//忽略的点
for (int i = iPtnNum - numToIgnore; i < iPtnNum; i++)
{
for (int i = iPtnNum - numToIgnore; i < iPtnNum; i++) {
taPoints[i].bValid = false;
}
fitCircle2D_wods(iPtnNum, &taPoints[0], tpCircle);
//计算RMS
for (int i = 0; i < iPtnNum; i++)
{
for (int i = 0; i < iPtnNum; i++) {
if (taPoints[i].bValid)
{
r = std::pow(calcDist(taPoints[i], tpCircle) - tpCircle.dR, 2);
......@@ -459,3 +439,65 @@ int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, double &RMS
return FUNC_OK;
}
static void fitCircle2D_wods(int iPtnNum, const EyemOcsDXY *taPoints, float *weights, float *circle)
{
//计算系数
double sa[9], sb[3];
cv::Mat a = cv::Mat(3, 3, CV_64F, sa), b = cv::Mat(3, 1, CV_64F, sb);
//系数矩阵A*X=B;
cv::Mat x = cv::Mat(3, 1, CV_64F);
memset(sa, 0, sizeof(sa));
memset(sb, 0, sizeof(sb));
for (int i = 0; i < iPtnNum; i++)
{
sa[0] += (double)weights[i] * taPoints[i].dX;
sa[1] += (double)weights[i] * taPoints[i].dY;
sa[2] += (double)weights[i];
sa[3] += (double)weights[i] * taPoints[i].dX*taPoints[i].dX;
sa[4] += (double)weights[i] * taPoints[i].dX*taPoints[i].dY;
sa[7] += (double)weights[i] * taPoints[i].dY*taPoints[i].dY;
sb[1] += (double)weights[i] * taPoints[i].dX*(-taPoints[i].dX*taPoints[i].dX - taPoints[i].dY*taPoints[i].dY);
sb[2] += (double)weights[i] * taPoints[i].dY*(-taPoints[i].dX*taPoints[i].dX - taPoints[i].dY*taPoints[i].dY);
}
sa[5] = sa[0];
sa[6] = sa[4];
sa[8] = sa[1];
sb[0] = -(sa[3] + sa[7]);
cv::solve(a, b, x, cv::DECOMP_SVD);
//tpCircle.dX = -x.ptr<double_t>(0)[0] / 2.0;
//tpCircle.dY = -x.ptr<double_t>(1)[0] / 2.0;
//tpCircle.dR = sqrt(pow(x.ptr<double_t>(0)[0], 2) + pow(x.ptr<double_t>(1)[0], 2) - 4.0*(x.ptr<double_t>(2)[0])) / 2.0;
}
int eyemRobustFitCircle(int iPtnNum, EyemOcsDXY *taPoints, int iCalcMode, double dRobustCoef, EyemOcsDXYR &tpCircle)
{
return FUNC_OK;
}
int eyemRobustFitPlane(int iPtnNum, EyemOcsDXYZ *taPoint, int iCalcMode, double dRobustCoef, EyemOcsDABCD &tpPlane)
{
return FUNC_OK;
}
int eyemFitPlane(int iPtnNum, EyemOcsDXYZ *taPoint, int numToIgnore, double &dRMS, EyemOcsDABCD &tpPlane)
{
return FUNC_OK;
}
int eyemFitLineRANSAC(int iPtnNum, EyemOcsDXY *taPoint, EyemOcsDABC &tpLine)
{
return FUNC_OK;
}
int eyemFitCircleRANSAC(int iPtnNum, EyemOcsDXY *taPoint, EyemOcsDXYR &tpCircle)
{
return FUNC_OK;
}
......@@ -7,7 +7,6 @@
#include <opencv.hpp>
#ifndef EXPORTS
#define EXPORTS __declspec(dllexport)
#endif
......@@ -431,7 +430,7 @@ extern "C" {
// 函数接口
EXPORTS int eyemFitLine(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, EyemOcsDABC &tpLine);
EXPORTS int eyemRobustFitLine(int iPtnNum, EyemOcsDXY *taPoint, int iCalcMode, double dRobustCoef, EyemOcsDABC &tpLine);
EXPORTS int eyemFitPlane(int, EyemOcsDXYZ[], int, double, EyemOcsDABCD *);
EXPORTS int eyemFitPlane(int, EyemOcsDXYZ[], int, double, EyemOcsDABCD &);
EXPORTS int eyemFitCircle(int iPtnNum, EyemOcsDXY *taPoint, int numToIgnore, double &RMS, EyemOcsDXYR &tpCircle);
EXPORTS int eyemFitEllipse(int, EyemOcsDXY[], int, double, EyemOcsDXYLSQ *);
EXPORTS int eyemFitEllipseC(int, EyemOcsDXY[], int, double, double[]);
......@@ -659,7 +658,7 @@ extern "C" {
#endif
// 函数接口
EXPORTS int eyemEdgesPixel(EyemImage tpImage, double dThresh);
EXPORTS int eyemEdgesPixel(EyemImage tpImage, double dThreshold);
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);
......@@ -790,6 +789,27 @@ extern "C" {
//////////////////////////////////////////////////////////////////////////////////////////////
// 深度学习目标检测器(eyemNNDetector.cpp)
//
typedef struct {
EyemRect bboxes[100];
} BboxContainer;
#ifdef __cplusplus
extern "C" {
#endif
// 函数接口
EXPORTS int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModelPath);
EXPORTS int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container);
#ifdef __cplusplus
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////
// 其他工具(eyemMisc.cpp)
//
......
此文件类型无法预览
......@@ -177,8 +177,9 @@
<ClInclude Include="eyemMat.h" />
<ClInclude Include="eyemMath.h" />
<ClInclude Include="eyemMisc.h" />
<ClInclude Include="eyemNNDetector.h" />
<ClInclude Include="eyemSmooth.h" />
<ClInclude Include="nnDetector.h" />
<ClInclude Include="eyemCodeDetector.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="yoloWrapper.h" />
</ItemGroup>
......@@ -199,8 +200,9 @@
<ClCompile Include="eyemMatch.cpp" />
<ClCompile Include="eyemMath.cpp" />
<ClCompile Include="eyemMisc.cpp" />
<ClCompile Include="eyemNNDetector.cpp" />
<ClCompile Include="eyemSmooth.cpp" />
<ClCompile Include="nnDetector.cpp" />
<ClCompile Include="eyemCodeDetector.cpp" />
<ClCompile Include="libopencv.cpp" />
<ClCompile Include="yoloWrapper.cpp" />
</ItemGroup>
......
......@@ -57,15 +57,18 @@
<ClInclude Include="yoloWrapper.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="nnDetector.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="barcodeDetector.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemDataCode.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemCodeDetector.h">
<Filter>源文件</Filter>
</ClInclude>
<ClInclude Include="eyemNNDetector.h">
<Filter>源文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="eyemLib.cpp">
......@@ -119,15 +122,18 @@
<ClCompile Include="libopencv.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="nnDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="barcodeDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemDataCode.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemCodeDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="eyemNNDetector.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="eyemLib.rc">
......
#include "eyemNNDetector.h"
#include "yoloWrapper.h"
class NNDetector::Impl {
public:
Impl() {}
~Impl() {}
//目标检测
std::vector<cv::Rect> detect(const cv::Mat& img);
//目标检测器
std::shared_ptr<YoloWrapper> detector_;
};
NNDetector::NNDetector(const std::string & detector_config_path,
const std::string & detector_model_path)
{
p = cv::makePtr<NNDetector::Impl>();
if (!detector_config_path.empty() && !detector_model_path.empty()) {
p->detector_ = std::make_shared<YoloWrapper>();
p->detector_->init(detector_config_path, detector_model_path);
}
else {
p->detector_ = NULL;
}
}
std::vector<cv::Rect> NNDetector::detect(cv::InputArray img)
{
CV_Assert(!img.empty());
cv::Mat input;
int incn = img.channels();
if (incn == 4) {
cv::cvtColor(img, input, cv::COLOR_BGRA2BGR);
}
else if (incn == 1) {
cv::cvtColor(img, input, cv::COLOR_GRAY2BGR);//根据配置支持三通道图像
}
else {
input = img.getMat();
}
return p->detect(input);
}
std::vector<cv::Rect> NNDetector::Impl::detect(const cv::Mat& img) {
return detector_->forward(img);
}
int eyemInitNNDetector(const char *detectorConfigPath, const char *detectorModelPath)
{
try {
pNNDetector = cv::makePtr<NNDetector>(detectorConfigPath, detectorModelPath);
}
catch (const std::exception& e) {
std::cout << e.what() << std::endl;
return FUNC_CANNOT_CALC;
}
std::unique_ptr<NNDetector> dd;
dd.reset(new NNDetector(detectorConfigPath, detectorModelPath));
dd->detect(cv::Mat());
dd.reset();
return FUNC_OK;
}
int eyemNNDetector(EyemImage tpImage, int *ipNum, BboxContainer &container)
{
cv::Mat src = cv::Mat(tpImage.iHeight, tpImage.iWidth, MAKETYPE(tpImage.iDepth, tpImage.iChannels), tpImage.vpImage).clone();
if (src.empty()) {
return FUNC_IMAGE_NOT_EXIST;
}
auto target = pNNDetector->detect(src);
//结果
for (int i = 0; i < target.size() && i < 100; ++i) {
EyemRect bbox; bbox.iXs = target[i].x; bbox.iYs = target[i].y; bbox.iWidth = target[i].width; bbox.iHeight = target[i].height;
container.bboxes[i] = bbox;
}
*ipNum = static_cast<int>(target.size());
return FUNC_OK;
}
#pragma once
//
// eyemNNDetector¡¤±êÍ·
//
#ifndef __EYEMNNDETECTOR_H
#define __EYEMNNDETECTOR_H
#include "eyemLib.h"
class NNDetector {
public:
NNDetector(const std::string& detector_config_path = "",
const std::string& detector_model_path = "");
NNDetector() {};
std::vector<cv::Rect> detect(cv::InputArray img);
protected:
class Impl;
cv::Ptr<Impl> p;
};
cv::Ptr<NNDetector> pNNDetector;
#endif/* __EYEMNNDETECTOR_H */
\ No newline at end of file
#include "yoloWrapper.h"
int YoloWrapper::init(const cv::String& detector_config_path,
const cv::String& detector_model_path) {
int YoloWrapper::init(const std::string& detector_config_path,
const std::string& detector_model_path) {
if (!detector_config_path.empty() && !detector_model_path.empty()) {
//加载并初始化网络
net_ = cv::dnn::readNet(detector_config_path, detector_model_path);
......@@ -62,11 +62,9 @@ std::vector<cv::Rect> YoloWrapper::forward(cv::Mat img) {
}
}
}
std::vector<int> indices;
//非极大值抑制
cv::dnn::NMSBoxes(bboxes, confidences, 0.01f, 0.05f, indices);
//裁剪区域
auto points = std::vector<cv::Rect>();
for (int i = 0; i < indices.size(); i++) {
......
......@@ -13,7 +13,6 @@ class YoloWrapper
{
public:
YoloWrapper() {};
~YoloWrapper() {};
int init(const std::string& config_path, const std::string& model_path);
std::vector<cv::Rect> forward(cv::Mat img);
private:
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!