#include "Edge_Search.h" #include Edge_Search::Edge_Search() { bshowimg = false; } Edge_Search::~Edge_Search() { } // 计算平均值 double Edge_Search::computeAverage(const std::vector &data) { return std::accumulate(data.begin(), data.end(), 0.0) / data.size(); } // 剔除异常数据,这里以平均值加减两倍标准差为界限 std::vector Edge_Search::removeOutliers(const std::vector &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 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 &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 &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 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 &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> contours; std::vector 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 &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 &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 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 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 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 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; }