|
|
|
|
|
#include "Edge_Search.h"
|
|
|
#include <numeric>
|
|
|
Edge_Search::Edge_Search()
|
|
|
{
|
|
|
bshowimg = false;
|
|
|
}
|
|
|
|
|
|
Edge_Search::~Edge_Search()
|
|
|
{
|
|
|
}
|
|
|
// 计算平均值
|
|
|
double Edge_Search::computeAverage(const std::vector<double> &data)
|
|
|
{
|
|
|
return std::accumulate(data.begin(), data.end(), 0.0) / data.size();
|
|
|
}
|
|
|
|
|
|
// 剔除异常数据,这里以平均值加减两倍标准差为界限
|
|
|
std::vector<double> Edge_Search::removeOutliers(const std::vector<double> &data)
|
|
|
{
|
|
|
double mean = computeAverage(data);
|
|
|
double sq_sum = std::inner_product(data.begin(), data.end(), data.begin(), 0.0);
|
|
|
double stdev = std::sqrt(sq_sum / data.size() - mean * mean);
|
|
|
std::vector<double> filteredData;
|
|
|
for (double value : data)
|
|
|
{
|
|
|
if (std::abs(value - mean) <= 2 * stdev)
|
|
|
{ // 可以根据需要调整异常值判断的标准
|
|
|
filteredData.push_back(value);
|
|
|
}
|
|
|
}
|
|
|
return filteredData;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::Detect(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult)
|
|
|
{
|
|
|
|
|
|
m_pdetlog = pDetConfig->pdetlog;
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
m_pdetlog->bPrintStr = true;
|
|
|
}
|
|
|
int re = 0;
|
|
|
bool bdraw = pDetConfig->pEdgeROI->Use_DrawROI;
|
|
|
bool bAIDet = pDetConfig->pEdgeROI->Use_AIEdge;
|
|
|
bool bUseEdge = pDetConfig->pEdgeROI->Use_DetEdge;
|
|
|
if (pDetConfig->bMode_Edge_test)
|
|
|
{
|
|
|
bdraw = false;
|
|
|
bAIDet = true;
|
|
|
}
|
|
|
// 边缘搜索
|
|
|
if (bAIDet)
|
|
|
{
|
|
|
|
|
|
long ts = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s AI Detect start ", pDetConfig->strCamName.c_str());
|
|
|
re = Detect_AI(detimg, pDetConfig, pEdgeDetResult);
|
|
|
|
|
|
if (re != 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Error AI Detect re = %d", pDetConfig->strCamName.c_str(), re);
|
|
|
|
|
|
// 如果失败了,启用绘制的结果。
|
|
|
if (pDetConfig->pEdgeROI->AI_Fail_UseDraw)
|
|
|
{
|
|
|
bdraw = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return re;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bdraw = false; // 如果AI检测成功,则不使用绘制结果
|
|
|
long te = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s AI Detect Success time %ld ms", pDetConfig->strCamName.c_str(), te - ts);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (bdraw)
|
|
|
{
|
|
|
long ts = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s UseDraw ROI start", pDetConfig->strCamName.c_str());
|
|
|
re = Detect_Draw(detimg, pDetConfig, pEdgeDetResult);
|
|
|
if (re != 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Error UseDraw ROI re = %d", pDetConfig->strCamName.c_str(), re);
|
|
|
bUseEdge = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
long te = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s UseDraw ROI Success time %ld ms", pDetConfig->strCamName.c_str(), te - ts);
|
|
|
bUseEdge = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (bUseEdge)
|
|
|
{
|
|
|
long ts = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Search edge start", pDetConfig->strCamName.c_str());
|
|
|
re = Detect_Search(detimg, pDetConfig, pEdgeDetResult);
|
|
|
if (re != 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Error Search edge re = %d", pDetConfig->strCamName.c_str(), re);
|
|
|
return re;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
long te = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Search edge Success time %ld ms", pDetConfig->strCamName.c_str(), te - ts);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// getchar();
|
|
|
if (pDetConfig->bMode_Edge_test)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
// 特征定位
|
|
|
if (!pEdgeDetResult->shieldMask_Src.empty())
|
|
|
{
|
|
|
long ts = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Feature_Align start", pDetConfig->strCamName.c_str());
|
|
|
re = Feature_Align(detimg, pDetConfig, pEdgeDetResult);
|
|
|
if (re != 0)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Error Feature_Align re = %d", pDetConfig->strCamName.c_str(), re);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
long te = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_2, "Edge_Search", " cam %s Feature_Align Success time %ld ms", pDetConfig->strCamName.c_str(), te - ts);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::Detect_AI(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult)
|
|
|
{
|
|
|
Function_EdgeROI *pEdgeROI = pDetConfig->pEdgeROI;
|
|
|
AI_Edge_Algin::DetConfig AI_detConfig;
|
|
|
|
|
|
AI_detConfig.Init();
|
|
|
AI_detConfig.saveProcessImg = AI_Edge_Algin::Save_Close;
|
|
|
AI_detConfig.nAIErodesize = pEdgeROI->AI_Erode_Size;
|
|
|
AI_detConfig.bUseDrawRoi_Check = pEdgeROI->AI_Fail_UseDraw;
|
|
|
AI_detConfig.ncamId = 0;
|
|
|
AI_detConfig.strCamName = pDetConfig->strCamName;
|
|
|
if (AI_detConfig.bUseDrawRoi_Check)
|
|
|
{
|
|
|
AI_detConfig.drawMask = pEdgeROI->EdgeMask;
|
|
|
}
|
|
|
|
|
|
if (pEdgeROI->pointArry1.size() <= 0)
|
|
|
{
|
|
|
AI_detConfig.bUseDrawRoi_Check = false;
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Edge_Search", "Draw roi param erro");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
AI_detConfig.drawRoi = cv::boundingRect(pEdgeROI->pointArry1);
|
|
|
}
|
|
|
|
|
|
if (pEdgeROI->EdgeMask.empty())
|
|
|
{
|
|
|
AI_detConfig.bUseDrawRoi_Check = false;
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Edge_Search", "Draw roi param erro");
|
|
|
}
|
|
|
|
|
|
if (pDetConfig->bMode_Edge_test)
|
|
|
{
|
|
|
AI_detConfig.bUseDrawRoi_Check = false;
|
|
|
AI_detConfig.saveProcessImg = AI_Edge_Algin::Save_Filter;
|
|
|
}
|
|
|
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
AI_detConfig.bDebugSaveImg = true;
|
|
|
}
|
|
|
|
|
|
std::shared_ptr<Edge_AI_Result> CheckResult_Aling;
|
|
|
// if (m_pAI_Edge_Algin.get() != nullptr)
|
|
|
{
|
|
|
|
|
|
int re = m_pAI_Edge_Algin.Detect(detimg, &AI_detConfig, CheckResult_Aling);
|
|
|
|
|
|
if (re != 0)
|
|
|
{
|
|
|
printf("AIEdgeDete error \n");
|
|
|
return re;
|
|
|
}
|
|
|
pEdgeDetResult->nresult = 0;
|
|
|
pEdgeDetResult->cutRoi = CheckResult_Aling->roi;
|
|
|
pEdgeDetResult->shieldMask = CheckResult_Aling->mask;
|
|
|
pEdgeDetResult->shieldMask_Src = CheckResult_Aling->DetMask_src;
|
|
|
pEdgeDetResult->pEdgeDet_roiList = CheckResult_Aling->edge_RoiList;
|
|
|
|
|
|
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Edge_Search", "pEdgeDet_roiList %ld", pEdgeDetResult->pEdgeDet_roiList->size());
|
|
|
// detMaskImg = CheckResult_Aling->mask.clone();
|
|
|
// roi = CheckResult_Aling->roi;
|
|
|
// detmask = CheckResult_Aling->DetMask_src.clone();
|
|
|
}
|
|
|
// getchar();
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::Detect_Draw(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult)
|
|
|
{
|
|
|
Function_EdgeROI *pEdgeROI = pDetConfig->pEdgeROI;
|
|
|
cv::Mat paraMaskImg = pEdgeROI->EdgeMask;
|
|
|
bool bsucc = false;
|
|
|
cv::Rect roi;
|
|
|
if (!paraMaskImg.empty())
|
|
|
{
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
cv::imwrite("draw_roi_1.png", paraMaskImg);
|
|
|
}
|
|
|
|
|
|
// cv::imwrite("paraMaskImg.png", paraMaskImg);
|
|
|
if (detimg.size() == paraMaskImg.size())
|
|
|
{
|
|
|
pEdgeDetResult->shieldMask_Src = paraMaskImg;
|
|
|
// m_DetEdge.detmask = paraMaskImg;
|
|
|
// 查找轮廓
|
|
|
std::vector<std::vector<cv::Point>> contours;
|
|
|
std::vector<cv::Vec4i> hierarchy;
|
|
|
cv::findContours(paraMaskImg, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
|
|
|
|
|
|
// 找到最大轮廓
|
|
|
int max_contour_index = -1;
|
|
|
double max_area = 0;
|
|
|
|
|
|
for (size_t i = 0; i < contours.size(); i++)
|
|
|
{
|
|
|
double area = cv::contourArea(contours[i]);
|
|
|
if (area > max_area)
|
|
|
{
|
|
|
max_area = area;
|
|
|
max_contour_index = i;
|
|
|
}
|
|
|
}
|
|
|
if (max_contour_index >= 0)
|
|
|
{
|
|
|
roi = cv::boundingRect(contours[max_contour_index]);
|
|
|
bsucc = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Detect_Draw", "Error DrMaskImg NO contours");
|
|
|
}
|
|
|
|
|
|
// 计算最大轮廓的外接矩形
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Detect_Draw", "Error DrMaskImg size != det img size");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Detect_Draw", "Error config MaskImg is empty");
|
|
|
}
|
|
|
if (!bsucc)
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if (roi.x < 0 || roi.y < 0 || roi.width <= 0 || roi.height <= 0)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
if (roi.x + roi.width > detimg.cols)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
if (roi.y + roi.height > detimg.rows)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
pEdgeDetResult->cutRoi = roi;
|
|
|
|
|
|
// 对绘制的边缘进行 精细处理
|
|
|
{
|
|
|
int thresholdvalue = pEdgeROI->threshold_value;
|
|
|
|
|
|
cv::Mat detMaskImg = paraMaskImg(roi).clone();
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
cv::imwrite("draw_roi_2.png", detMaskImg);
|
|
|
}
|
|
|
detMaskImg = ~detMaskImg;
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
cv::imwrite("draw_roi_3.png", detMaskImg);
|
|
|
}
|
|
|
if (thresholdvalue > 0)
|
|
|
{
|
|
|
int threshold_value = 11; // 你可以根据需要调整阈值
|
|
|
if (thresholdvalue >= 0 && thresholdvalue < 255)
|
|
|
{
|
|
|
threshold_value = thresholdvalue;
|
|
|
}
|
|
|
int max_value = 255; // 最大像素值,白色
|
|
|
int threshold_type = cv::THRESH_BINARY_INV; // 将高于阈值的像素设为白色,低于阈值的像素设为黑色
|
|
|
|
|
|
cv::Mat temimg;
|
|
|
cv::threshold(detimg(roi), temimg, threshold_value, max_value, threshold_type);
|
|
|
printf("threshold_value %d\n", threshold_value);
|
|
|
// 定义膨胀核
|
|
|
int dilation_size = 3; // 膨胀核的大小
|
|
|
if (pEdgeROI->AI_Erode_Size > 0 && pEdgeROI->AI_Erode_Size < 101)
|
|
|
{
|
|
|
dilation_size = 2 * pEdgeROI->AI_Erode_Size;
|
|
|
}
|
|
|
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(dilation_size, dilation_size));
|
|
|
|
|
|
// 进行膨胀操作
|
|
|
cv::Mat dilated_image;
|
|
|
cv::dilate(temimg, dilated_image, kernel);
|
|
|
printf("detMaskImg= %d %d %d\n", detMaskImg.cols, detMaskImg.rows, detMaskImg.channels());
|
|
|
printf("dilated_image= %d %d %d\n", dilated_image.cols, dilated_image.rows, dilated_image.channels());
|
|
|
detMaskImg += dilated_image;
|
|
|
}
|
|
|
pEdgeDetResult->shieldMask = detMaskImg;
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
cv::imwrite("draw_roi_4.png", pEdgeDetResult->shieldMask);
|
|
|
}
|
|
|
pEdgeDetResult->nresult = 0;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::Detect_Search(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult)
|
|
|
{
|
|
|
cv::Rect roi;
|
|
|
|
|
|
int re = SearchEdge(detimg, roi, pDetConfig->bDebugsaveImg);
|
|
|
if (re < 0)
|
|
|
{
|
|
|
return re;
|
|
|
}
|
|
|
|
|
|
if (roi.x < 0 || roi.y < 0 || roi.width <= 0 || roi.height <= 0)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
if (roi.x + roi.width > detimg.cols)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
if (roi.y + roi.height > detimg.rows)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
cv::Mat detMaskImg = cv::Mat(roi.height, roi.width, CV_8U, cv::Scalar(0));
|
|
|
int thresholdvalue = pDetConfig->pEdgeROI->threshold_value;
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
{
|
|
|
int detH = 60;
|
|
|
cv::Rect cutroi;
|
|
|
cv::Rect maskRoi;
|
|
|
|
|
|
switch (i)
|
|
|
{
|
|
|
case 0:
|
|
|
cutroi.x = roi.x;
|
|
|
cutroi.y = roi.y;
|
|
|
|
|
|
cutroi.width = roi.width;
|
|
|
cutroi.height = detH;
|
|
|
|
|
|
maskRoi.x = 0;
|
|
|
maskRoi.y = 0;
|
|
|
maskRoi.width = roi.width;
|
|
|
maskRoi.height = detH;
|
|
|
break;
|
|
|
case 1:
|
|
|
cutroi.x = roi.x;
|
|
|
cutroi.y = roi.y + roi.height - detH;
|
|
|
|
|
|
cutroi.width = roi.width;
|
|
|
cutroi.height = detH;
|
|
|
|
|
|
maskRoi.x = 0;
|
|
|
maskRoi.y = roi.height - detH;
|
|
|
maskRoi.width = roi.width;
|
|
|
maskRoi.height = detH;
|
|
|
|
|
|
break;
|
|
|
case 2:
|
|
|
|
|
|
cutroi.x = roi.x;
|
|
|
cutroi.y = roi.y;
|
|
|
|
|
|
cutroi.width = detH;
|
|
|
cutroi.height = roi.height;
|
|
|
|
|
|
maskRoi.x = 0;
|
|
|
maskRoi.y = 0;
|
|
|
maskRoi.width = detH;
|
|
|
maskRoi.height = roi.height;
|
|
|
|
|
|
break;
|
|
|
case 3:
|
|
|
cutroi.x = roi.x + roi.width - detH;
|
|
|
cutroi.y = roi.y;
|
|
|
|
|
|
cutroi.width = detH;
|
|
|
cutroi.height = roi.height;
|
|
|
|
|
|
maskRoi.x = roi.width - detH;
|
|
|
maskRoi.y = 0;
|
|
|
maskRoi.width = detH;
|
|
|
maskRoi.height = roi.height;
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
int threshold_value = 11; // 你可以根据需要调整阈值
|
|
|
if (thresholdvalue >= 0 && thresholdvalue < 255)
|
|
|
{
|
|
|
threshold_value = thresholdvalue;
|
|
|
}
|
|
|
|
|
|
int max_value = 255; // 最大像素值,白色
|
|
|
int threshold_type = cv::THRESH_BINARY_INV; // 将高于阈值的像素设为白色,低于阈值的像素设为黑色
|
|
|
cv::Mat temimg;
|
|
|
cv::threshold(detimg(cutroi), temimg, threshold_value, max_value, threshold_type);
|
|
|
// 定义膨胀核
|
|
|
int dilation_size = 4; // 膨胀核的大小
|
|
|
|
|
|
if (pDetConfig->pEdgeROI->AI_Erode_Size > 0 && pDetConfig->pEdgeROI->AI_Erode_Size < 101)
|
|
|
{
|
|
|
dilation_size = 2 * pDetConfig->pEdgeROI->AI_Erode_Size;
|
|
|
}
|
|
|
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(dilation_size, dilation_size));
|
|
|
|
|
|
// 进行膨胀操作
|
|
|
cv::Mat dilated_image;
|
|
|
cv::dilate(temimg, detMaskImg(maskRoi), kernel);
|
|
|
}
|
|
|
|
|
|
pEdgeDetResult->nresult = 0;
|
|
|
pEdgeDetResult->cutRoi = roi;
|
|
|
pEdgeDetResult->shieldMask = detMaskImg;
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
cv::imwrite(pDetConfig->strCamName + "8_Search_result.png", pEdgeDetResult->shieldMask);
|
|
|
cv::imwrite(pDetConfig->strCamName + "8_Search_result_src.png", detimg(roi));
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::SearchEdge(const cv::Mat &detimg, cv::Rect &roi, bool bsave)
|
|
|
{
|
|
|
bool bdetSucc = false;
|
|
|
|
|
|
cv::Mat img = detimg;
|
|
|
bshowimg = bsave;
|
|
|
if (bshowimg)
|
|
|
{
|
|
|
cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
|
|
|
}
|
|
|
int exp = 0;
|
|
|
cv::Rect detroi;
|
|
|
detroi.x = 0;
|
|
|
detroi.y = 0;
|
|
|
detroi.width = img.cols;
|
|
|
detroi.height = img.rows * 0.8;
|
|
|
int re = UDNoiseEdgeDetect(img, 3, 40, 1, detroi, 30, 60);
|
|
|
if (re < 0)
|
|
|
{
|
|
|
printf("edge error 1 %d \n", re);
|
|
|
return re;
|
|
|
}
|
|
|
roi.y = re + exp;
|
|
|
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
cv::Point p1 = cv::Point(0, re);
|
|
|
cv::Point p2 = cv::Point(img.cols, re);
|
|
|
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
|
|
|
printf(">>>>>1>>000000>\n");
|
|
|
}
|
|
|
// cv::Point p1 = cv::Point(0, re);
|
|
|
// cv::Point p2 = cv::Point(img.cols, re);
|
|
|
// cv::line(img, p1, p2, cv::Scalar(255));
|
|
|
|
|
|
detroi.x = 0;
|
|
|
detroi.y = img.rows * 0.2;
|
|
|
detroi.width = img.cols;
|
|
|
detroi.height = img.rows * 0.8 - 1;
|
|
|
re = UDNoiseEdgeDetect(img, -3, 40, 10, detroi, 30, 60);
|
|
|
if (re < 0)
|
|
|
{
|
|
|
printf("edge error 2 %d \n", re);
|
|
|
return re;
|
|
|
}
|
|
|
roi.height = re - exp - roi.y;
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
cv::Point p1 = cv::Point(0, re);
|
|
|
cv::Point p2 = cv::Point(img.cols, re);
|
|
|
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
|
|
|
}
|
|
|
|
|
|
// p1 = cv::Point(0, re);
|
|
|
// p2 = cv::Point(img.cols, re);
|
|
|
// cv::line(img, p1, p2, cv::Scalar(255));
|
|
|
// cv::imwrite("showimg.png", img);
|
|
|
// printf(">>>>>>>>\n");
|
|
|
// getchar();
|
|
|
|
|
|
detroi.x = 0;
|
|
|
detroi.y = 0;
|
|
|
detroi.width = img.cols / 2;
|
|
|
detroi.height = img.rows;
|
|
|
re = LRNoiseEdgeDetect(img, 3, 40, 1, detroi, 30, 60);
|
|
|
if (re < 0)
|
|
|
{
|
|
|
printf("edge error 333 v %d \n", re);
|
|
|
return re;
|
|
|
}
|
|
|
roi.x = re + exp;
|
|
|
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
cv::Point p1 = cv::Point(re, 0);
|
|
|
cv::Point p2 = cv::Point(re, img.rows);
|
|
|
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
|
|
|
}
|
|
|
// p1 = cv::Point(re, 0);
|
|
|
// p2 = cv::Point(re, img.rows);
|
|
|
// cv::line(img, p1, p2, cv::Scalar(255));
|
|
|
// cv::imwrite("showimg.png", img);
|
|
|
// printf(">>>>>>>>\n");
|
|
|
// getchar();
|
|
|
// cv::imwrite("showimg.png", showimg);
|
|
|
// printf(">>>>>1>>>re %d\n", re);
|
|
|
// getchar();
|
|
|
detroi.x = img.cols / 2;
|
|
|
detroi.y = 0;
|
|
|
detroi.width = img.cols / 2 - 1;
|
|
|
detroi.height = img.rows;
|
|
|
re = LRNoiseEdgeDetect(img, -3, 40, 1, detroi, 30, 60);
|
|
|
if (re < 0)
|
|
|
{
|
|
|
printf(">>>>>>>>\n");
|
|
|
printf("edge error 4 %d \n", re);
|
|
|
return re;
|
|
|
}
|
|
|
roi.width = re - exp - roi.x;
|
|
|
// int len = roi.width / 4 * 4;
|
|
|
// roi.width = len;
|
|
|
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
|
|
|
cv::Point p1 = cv::Point(re, 0);
|
|
|
cv::Point p2 = cv::Point(re, img.rows);
|
|
|
cv::line(showimg, p1, p2, cv::Scalar(255, 0, 255), 5);
|
|
|
cv::rectangle(showimg, roi, cv::Scalar(0, 255, 0));
|
|
|
}
|
|
|
|
|
|
// cv::Mat temimg = showimg(real_roi).clone();
|
|
|
|
|
|
// if (real_roi.width > real_roi.height)
|
|
|
// {
|
|
|
// sz.width = 2048;
|
|
|
// fx = sz.width * 1.0f / real_roi.width;
|
|
|
// sz.height = real_roi.height * fx;
|
|
|
// }
|
|
|
// else
|
|
|
// {
|
|
|
// sz.height = 2048;
|
|
|
// fx = sz.height * 1.0f / real_roi.height;
|
|
|
// sz.width = real_roi.width * fx;
|
|
|
// }
|
|
|
|
|
|
// cv::resize(temimg, showimg, sz);
|
|
|
|
|
|
if (bshowimg && !showimg.empty() && true)
|
|
|
{
|
|
|
|
|
|
printf(">>>>>>>>\n");
|
|
|
static int ssss = 0;
|
|
|
|
|
|
cv::Size sz;
|
|
|
|
|
|
if (img.cols > img.rows)
|
|
|
{
|
|
|
sz.width = 2732;
|
|
|
sz.height = 2048;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sz.width = 2048;
|
|
|
sz.height = 2732;
|
|
|
}
|
|
|
|
|
|
// cv::Mat detsizeimg;
|
|
|
cv::resize(showimg, showimg, sz);
|
|
|
// std::string strpath22 = "./img/edge/" + std::to_string(ssss++) + "_det.png";
|
|
|
// printf(">>>>>>>>strpath22 %s\n", strpath22.c_str());
|
|
|
// cv::imwrite(strpath22, detsizeimg);
|
|
|
|
|
|
// std::string strpath22222 = "./img/edge/" + std::to_string(ssss++) + "_src.png";
|
|
|
// printf(">>>>>>>>strpath22 %s\n", strpath22.c_str());
|
|
|
// cv::imwrite(strpath22222, img);
|
|
|
|
|
|
cv::imwrite("showimg.png", showimg);
|
|
|
printf(">>>>>>>>\n");
|
|
|
}
|
|
|
|
|
|
// p1 = cv::Point(re, 0);
|
|
|
// p2 = cv::Point(re, img.rows);
|
|
|
// cv::line(img, p1, p2, cv::Scalar(255));
|
|
|
// cv::imwrite("showimg.png", img);
|
|
|
// printf(">>>>>>>>\n");
|
|
|
// getchar();
|
|
|
// cv::rectangle(img, roi, cv::Scalar(255));
|
|
|
// cv::imwrite("showimg.png", img);
|
|
|
// printf(">>>>>>>>\n");
|
|
|
// getchar();
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::Feature_Align(const cv::Mat &detimg, DetConfigResult *pDetConfig, std::shared_ptr<EdgeDetResult> &pEdgeDetResult)
|
|
|
{
|
|
|
|
|
|
// 1、要使用 AI 搜边。
|
|
|
// 2、对齐开关要开启
|
|
|
// 3、特征maks不为空
|
|
|
// 4、边缘mask不为空
|
|
|
cv::Rect Det_CropRoi = pEdgeDetResult->cutRoi;
|
|
|
cv::Mat detImg_mask = pEdgeDetResult->shieldMask_Src;
|
|
|
|
|
|
if (!pDetConfig->pAlign)
|
|
|
{
|
|
|
return 1;
|
|
|
}
|
|
|
std::string strlog = "";
|
|
|
Function_Image_Align *pAlign;
|
|
|
pAlign = pDetConfig->pAlign;
|
|
|
|
|
|
if (pAlign->bOpen &&
|
|
|
!pAlign->feature_Mask.empty())
|
|
|
{
|
|
|
// cv::imwrite("Align_search_img.png", m_DetEdge.detmask(pFuntion_L255->function.f_Image_Align.search_Roi).clone());
|
|
|
// cv::imwrite("Align_Kernel_img.png", pFuntion_L255->function.f_Image_Align.feature_Mask);
|
|
|
// cv::imwrite("detmaskssss.png", m_DetEdge.detmask);
|
|
|
// cv::imwrite("ssss.png", L255->in_shareImage->img);
|
|
|
CheckUtil::printROI(Det_CropRoi, "Det Img Crop Roi");
|
|
|
CheckUtil::printROI(pAlign->Crop_Roi, "Param Img Crop Roi");
|
|
|
Image_Feature_Algin::DetConfig detconfig;
|
|
|
detconfig.DetImg = detImg_mask;
|
|
|
detconfig.TemplateImg = pAlign->feature_Mask;
|
|
|
detconfig.Search_Roi = pAlign->search_Roi;
|
|
|
detconfig.feature_Roi = pAlign->feature_Roi;
|
|
|
detconfig.param_CropRoi = pAlign->Crop_Roi;
|
|
|
detconfig.DetImg_CropROi = Det_CropRoi;
|
|
|
detconfig.bSaveImg = pDetConfig->bDebugsaveImg;
|
|
|
detconfig.fscore = pAlign->fscore;
|
|
|
|
|
|
long t1 = CheckUtil::getcurTime();
|
|
|
m_Image_Feature_Algin.Detect(&detconfig, &pEdgeDetResult->m_align_Result, m_pdetlog->logList);
|
|
|
long t2 = CheckUtil::getcurTime();
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Image_Align", "use time %ld ", t2 - t1);
|
|
|
|
|
|
pEdgeDetResult->m_align_Result.bDraw = pAlign->bDraw;
|
|
|
|
|
|
// 对齐成功
|
|
|
if (pEdgeDetResult->m_align_Result.bDet)
|
|
|
{
|
|
|
if (pAlign->runType == Function_Image_Align::type_Use)
|
|
|
{
|
|
|
pEdgeDetResult->m_align_Result.bUse = true;
|
|
|
}
|
|
|
// 更新 特征图像区域在检测图片上的位置。
|
|
|
for (const auto &point : pAlign->pointArry1)
|
|
|
{
|
|
|
cv::Point p = point;
|
|
|
cv::Point ss = pEdgeDetResult->m_align_Result.Parm_srcToDet_Crop_Point(p);
|
|
|
pEdgeDetResult->m_align_Result.feature_PointList_DetImg.push_back(ss);
|
|
|
}
|
|
|
|
|
|
if (pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.x < 0)
|
|
|
{
|
|
|
pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.x = 0;
|
|
|
}
|
|
|
if (pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.x + pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.width > detimg.cols)
|
|
|
{
|
|
|
pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.x = detimg.cols - pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.width;
|
|
|
}
|
|
|
if (pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.y < 0)
|
|
|
{
|
|
|
pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.y = 0;
|
|
|
}
|
|
|
if (pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.y + pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.height > detimg.rows)
|
|
|
{
|
|
|
pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.y = detimg.rows - pEdgeDetResult->m_align_Result.Crop_Roi_ParmImg.height;
|
|
|
}
|
|
|
|
|
|
if (pDetConfig->bDebugsaveImg)
|
|
|
{
|
|
|
// 绘制对齐
|
|
|
|
|
|
{
|
|
|
cv::Mat showimg;
|
|
|
cv::cvtColor(detimg(Det_CropRoi), showimg, cv::COLOR_GRAY2BGR);
|
|
|
|
|
|
cv::polylines(showimg, pEdgeDetResult->m_align_Result.feature_PointList_DetImg, true, cv::Scalar(255, 255, 0), 2);
|
|
|
|
|
|
cv::imwrite("align_Result.png", showimg);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (!pAlign->bOpen)
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Image_Align", "-- error :Align Param Close");
|
|
|
}
|
|
|
else if (pAlign->feature_Mask.empty())
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Image_Align", " -- error :AI Edge Det Error");
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pdetlog->AddCheckstr(PrintLevel_3, "Image_Align", " -- error :Align Param Error");
|
|
|
}
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::UDNoiseEdgeDetect(cv::Mat img, int DirectSign, int Gate, int BorW, cv::Rect roi, int StepCount, int Limit)
|
|
|
{
|
|
|
|
|
|
if (img.empty())
|
|
|
{
|
|
|
return -11;
|
|
|
}
|
|
|
if (img.channels() != 1)
|
|
|
{
|
|
|
printf("*****************************channels\n");
|
|
|
|
|
|
return -12;
|
|
|
}
|
|
|
if (StepCount < 0 || StepCount >= roi.width)
|
|
|
{
|
|
|
printf("*****************************StepCount\n");
|
|
|
|
|
|
return -22;
|
|
|
}
|
|
|
std::vector<double> data;
|
|
|
// cv::Mat showimg;
|
|
|
// cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
|
|
|
uchar *pdata = (uchar *)img.data;
|
|
|
|
|
|
int sx = roi.x;
|
|
|
int ex = roi.x + roi.width;
|
|
|
int sy = roi.y;
|
|
|
int ey = roi.y + roi.height;
|
|
|
// 表示 反向搜索
|
|
|
if (DirectSign < 0)
|
|
|
{
|
|
|
sy = roi.y + roi.height;
|
|
|
ey = roi.y;
|
|
|
}
|
|
|
int step = roi.width / StepCount;
|
|
|
int offt = 0;
|
|
|
int sumsite = 0;
|
|
|
int sumcount = 0;
|
|
|
// 表示搜索黑点
|
|
|
if (BorW == 0)
|
|
|
{
|
|
|
}
|
|
|
else // 表示搜索白点
|
|
|
{
|
|
|
for (int x = roi.x; x < ex; x = x + step)
|
|
|
{
|
|
|
|
|
|
int ncount = 0;
|
|
|
int start = 0;
|
|
|
|
|
|
for (int y = sy;; y = y + DirectSign)
|
|
|
{
|
|
|
if (DirectSign > 0 && y > ey)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
if (DirectSign < 0 && y < ey)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
int maxv = 0;
|
|
|
// 1、计算当前值是否 满足基本要求
|
|
|
offt = y * img.cols + x;
|
|
|
maxv = pdata[offt];
|
|
|
|
|
|
if (maxv < 40)
|
|
|
{
|
|
|
for (int ix = -4; ix < 5; ix++)
|
|
|
{
|
|
|
int newx = x + ix;
|
|
|
if (newx < 0)
|
|
|
{
|
|
|
newx = 0;
|
|
|
}
|
|
|
if (newx > img.cols)
|
|
|
{
|
|
|
newx = img.cols;
|
|
|
}
|
|
|
|
|
|
offt = y * img.cols + newx;
|
|
|
|
|
|
if (pdata[offt] > maxv)
|
|
|
{
|
|
|
maxv = pdata[offt];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (maxv > 40)
|
|
|
{
|
|
|
// 2、计算区域最大值
|
|
|
for (int k = -4; k < 5; k++)
|
|
|
{
|
|
|
int newy = y + k;
|
|
|
if (newy < 0)
|
|
|
{
|
|
|
newy = 0;
|
|
|
}
|
|
|
if (newy >= img.rows)
|
|
|
{
|
|
|
newy = img.rows - 1;
|
|
|
}
|
|
|
|
|
|
for (int ix = -4; ix < 5; ix++)
|
|
|
{
|
|
|
int newx = x + ix;
|
|
|
if (newx < 0)
|
|
|
{
|
|
|
newx = 0;
|
|
|
}
|
|
|
if (newx > img.cols)
|
|
|
{
|
|
|
newx = img.cols;
|
|
|
}
|
|
|
|
|
|
offt = newy * img.cols + newx;
|
|
|
|
|
|
if (pdata[offt] > maxv)
|
|
|
{
|
|
|
maxv = pdata[offt];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* code */
|
|
|
}
|
|
|
if (bshowimg)
|
|
|
{
|
|
|
cv::Rect roi;
|
|
|
roi.x = x - 2;
|
|
|
roi.width = 5;
|
|
|
if (roi.x < 0)
|
|
|
{
|
|
|
roi.x = 0;
|
|
|
}
|
|
|
int rdp = roi.x + roi.width;
|
|
|
if (rdp > showimg.cols)
|
|
|
{
|
|
|
rdp = showimg.cols;
|
|
|
}
|
|
|
roi.width = rdp - roi.x;
|
|
|
|
|
|
roi.y = y - 2;
|
|
|
roi.height = 5;
|
|
|
if (roi.y < 0)
|
|
|
{
|
|
|
roi.y = 0;
|
|
|
}
|
|
|
rdp = roi.y + roi.height;
|
|
|
if (rdp > showimg.rows)
|
|
|
{
|
|
|
rdp = showimg.rows;
|
|
|
}
|
|
|
roi.height = rdp - roi.y;
|
|
|
cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255));
|
|
|
/* code */
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// if (start > 0)
|
|
|
// {
|
|
|
// printf("error p %d %d %d \n", x, y, maxv);
|
|
|
// /* code */
|
|
|
// }
|
|
|
}
|
|
|
// 3、满足要求 记录
|
|
|
if (maxv >= Gate)
|
|
|
{
|
|
|
ncount += 2;
|
|
|
if (start == 0)
|
|
|
{
|
|
|
start = y;
|
|
|
}
|
|
|
if (ncount > Limit)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// if (maxv < 15)
|
|
|
// {
|
|
|
// ncount = 0;
|
|
|
// }
|
|
|
ncount--;
|
|
|
if (ncount < 0)
|
|
|
{
|
|
|
ncount = 0;
|
|
|
start = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
// 4、满足退出要求,就退出
|
|
|
if (ncount > Limit)
|
|
|
{
|
|
|
sumcount++;
|
|
|
sumsite += start;
|
|
|
data.push_back(start);
|
|
|
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
cv::Point p(x, start);
|
|
|
cv::circle(showimg, p, 13, cv::Scalar(0, 255, 0), 5);
|
|
|
// cv::imwrite("showimg.png", showimg);
|
|
|
// printf(">>>>>>>> %d %d \n",x,start);
|
|
|
// getchar();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (sumcount <= 0)
|
|
|
{
|
|
|
return -3;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 先剔除异常数据
|
|
|
std::vector<double> filteredData = removeOutliers(data);
|
|
|
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
|
|
|
// for (int i = 0; i < data.size(); i++)
|
|
|
// {
|
|
|
// printf("%d %f \n ", i, data.at(i));
|
|
|
// }
|
|
|
|
|
|
// for (int i = 0; i < filteredData.size(); i++)
|
|
|
// {
|
|
|
// printf("%d %f \n ", i, filteredData.at(i));
|
|
|
// }
|
|
|
}
|
|
|
sumsite = 0;
|
|
|
sumcount = 0;
|
|
|
int mean = 0;
|
|
|
for (int i = 0; i < filteredData.size(); i++)
|
|
|
{
|
|
|
sumsite += filteredData.at(i);
|
|
|
sumcount++;
|
|
|
}
|
|
|
if (sumcount > 0)
|
|
|
{
|
|
|
mean = sumsite / sumcount;
|
|
|
}
|
|
|
|
|
|
mean = sumsite / sumcount;
|
|
|
return mean;
|
|
|
}
|
|
|
|
|
|
return -5;
|
|
|
}
|
|
|
|
|
|
int Edge_Search::LRNoiseEdgeDetect(cv::Mat img, int DirectSign, int Gate, int BorW, cv::Rect roi, int StepCount, int Limit)
|
|
|
{
|
|
|
if (img.empty())
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
if (img.channels() != 1)
|
|
|
{
|
|
|
printf("*****************************channels\n");
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
if (StepCount < 0 || StepCount >= roi.width)
|
|
|
{
|
|
|
printf("*****************************StepCount\n");
|
|
|
|
|
|
return -2;
|
|
|
}
|
|
|
|
|
|
std::vector<double> data;
|
|
|
// cv::Mat showimg;
|
|
|
// cv::cvtColor(img, showimg, cv::COLOR_GRAY2BGR);
|
|
|
uchar *pdata = (uchar *)img.data;
|
|
|
|
|
|
int sx = roi.x;
|
|
|
int ex = roi.x + roi.width;
|
|
|
int sy = roi.y;
|
|
|
int ey = roi.y + roi.height;
|
|
|
// 表示 反向搜索
|
|
|
if (DirectSign < 0)
|
|
|
{
|
|
|
sx = roi.x + roi.width;
|
|
|
ex = roi.x;
|
|
|
}
|
|
|
int step = roi.height / StepCount;
|
|
|
int offt = 0;
|
|
|
int sumsite = 0;
|
|
|
int sumcount = 0;
|
|
|
// 表示搜索黑点
|
|
|
if (BorW == 0)
|
|
|
{
|
|
|
}
|
|
|
else // 表示搜索白点
|
|
|
{
|
|
|
// printf("---- y sy %d ey %d sx %d ex %d\n", sy, ey, sx, ex);
|
|
|
for (int y = sy; y < ey; y = y + step)
|
|
|
{
|
|
|
int ncount = 0;
|
|
|
int start = 0;
|
|
|
|
|
|
for (int x = sx;; x = x + DirectSign)
|
|
|
{
|
|
|
if (DirectSign > 0 && x > ex)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
if (DirectSign < 0 && x < ex)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
int maxv = 0;
|
|
|
// 1、计算当前值是否 满足基本要求
|
|
|
offt = y * img.cols + x;
|
|
|
maxv = pdata[offt];
|
|
|
if (maxv < 40)
|
|
|
{
|
|
|
for (int k = -4; k < 5; k++)
|
|
|
{
|
|
|
int newy = y + k;
|
|
|
if (newy < 0)
|
|
|
{
|
|
|
newy = 0;
|
|
|
}
|
|
|
if (newy >= img.rows)
|
|
|
{
|
|
|
newy = img.rows - 1;
|
|
|
}
|
|
|
offt = newy * img.cols + x;
|
|
|
maxv = pdata[offt];
|
|
|
if (pdata[offt] > maxv)
|
|
|
{
|
|
|
maxv = pdata[offt];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (maxv > 40)
|
|
|
{
|
|
|
// 2、计算区域最大值
|
|
|
for (int k = -4; k < 5; k++)
|
|
|
{
|
|
|
int newy = y + k;
|
|
|
if (newy < 0)
|
|
|
{
|
|
|
newy = 0;
|
|
|
}
|
|
|
if (newy >= img.rows)
|
|
|
{
|
|
|
newy = img.rows - 1;
|
|
|
}
|
|
|
|
|
|
for (int ix = -4; ix < 5; ix++)
|
|
|
{
|
|
|
int newx = x + ix;
|
|
|
if (newx < 0)
|
|
|
{
|
|
|
newx = 0;
|
|
|
}
|
|
|
if (newx > img.cols)
|
|
|
{
|
|
|
newx = img.cols;
|
|
|
}
|
|
|
|
|
|
offt = newy * img.cols + newx;
|
|
|
|
|
|
if (pdata[offt] > maxv)
|
|
|
{
|
|
|
maxv = pdata[offt];
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* code */
|
|
|
}
|
|
|
if (bshowimg)
|
|
|
{
|
|
|
cv::Rect roi;
|
|
|
roi.x = x - 2;
|
|
|
roi.width = 5;
|
|
|
if (roi.x < 0)
|
|
|
{
|
|
|
roi.x = 0;
|
|
|
}
|
|
|
int rdp = roi.x + roi.width;
|
|
|
if (rdp > showimg.cols)
|
|
|
{
|
|
|
rdp = showimg.cols;
|
|
|
}
|
|
|
roi.width = rdp - roi.x;
|
|
|
|
|
|
roi.y = y - 2;
|
|
|
roi.height = 5;
|
|
|
if (roi.y < 0)
|
|
|
{
|
|
|
roi.y = 0;
|
|
|
}
|
|
|
rdp = roi.y + roi.height;
|
|
|
if (rdp > showimg.rows)
|
|
|
{
|
|
|
rdp = showimg.rows;
|
|
|
}
|
|
|
roi.height = rdp - roi.y;
|
|
|
cv::rectangle(showimg, roi, cv::Scalar(0, 0, 255));
|
|
|
/* code */
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// if (start > 0)
|
|
|
// {
|
|
|
// //printf("error p %d %d %d \n", x, y, maxv);
|
|
|
// /* code */
|
|
|
// }
|
|
|
}
|
|
|
// 3、满足要求 记录
|
|
|
|
|
|
if (maxv >= Gate)
|
|
|
{
|
|
|
ncount += 2;
|
|
|
if (start == 0)
|
|
|
{
|
|
|
start = x;
|
|
|
// printf("---- %d %d y %d\n", pdata[offt], start, y);
|
|
|
}
|
|
|
if (ncount > Limit)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// if (maxv < 15)
|
|
|
// {
|
|
|
// ncount = 0;
|
|
|
// }
|
|
|
ncount--;
|
|
|
if (ncount < 0)
|
|
|
{
|
|
|
start = 0;
|
|
|
ncount = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
if (ncount > Limit)
|
|
|
{
|
|
|
sumcount++;
|
|
|
sumsite += start;
|
|
|
data.push_back(start);
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
cv::Point p(start, y);
|
|
|
cv::circle(showimg, p, 13, cv::Scalar(255, 255, 125), 5);
|
|
|
// cv::imwrite("showimg.png", showimg);
|
|
|
// printf(">>>>>>>>\n");
|
|
|
// getchar();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// if (bshowimg && !showimg.empty())
|
|
|
// {
|
|
|
// cv::imwrite("showimg.png", showimg);
|
|
|
// printf(">>>>>>123>> DirectSign %d \n",DirectSign);
|
|
|
// getchar();
|
|
|
// }
|
|
|
// if (DirectSign < 0)
|
|
|
// {
|
|
|
|
|
|
// cv::imwrite("showimg.png", img);
|
|
|
// printf(">>>>>>>>\n");
|
|
|
// getchar();
|
|
|
// }
|
|
|
if (sumcount <= 0)
|
|
|
{
|
|
|
return -3;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
|
|
|
// 先剔除异常数据
|
|
|
std::vector<double> filteredData = removeOutliers(data);
|
|
|
|
|
|
if (bshowimg && !showimg.empty())
|
|
|
{
|
|
|
|
|
|
// for (int i = 0; i < data.size(); i++)
|
|
|
// {
|
|
|
// printf("%d %f \n ", i, data.at(i));
|
|
|
// }
|
|
|
|
|
|
// for (int i = 0; i < filteredData.size(); i++)
|
|
|
// {
|
|
|
// printf("%d %f \n ", i, filteredData.at(i));
|
|
|
// }
|
|
|
}
|
|
|
sumsite = 0;
|
|
|
sumcount = 0;
|
|
|
int mean = 0;
|
|
|
for (int i = 0; i < filteredData.size(); i++)
|
|
|
{
|
|
|
sumsite += filteredData.at(i);
|
|
|
sumcount++;
|
|
|
}
|
|
|
if (sumcount > 0)
|
|
|
{
|
|
|
mean = sumsite / sumcount;
|
|
|
}
|
|
|
|
|
|
mean = sumsite / sumcount;
|
|
|
return mean;
|
|
|
}
|
|
|
|
|
|
return -5;
|
|
|
}
|