int BlockLocalizer::getXOnRow(cv::Point startPoint, int range, bool scanLeft2right) { const int roiHeight = 11;//所取ROI宽度,一定为奇数,输入的x值为ROI的中心 //创建roi范围,并防止越界。 cv::Rect roiRect(0, 0, range, roiHeight); roiRect.x = startPoint.x - range / 2; roiRect.y = startPoint.y - roiHeight / 2; rectFix(roiRect); if (roiRect.width > ContinuePointCount && roiRect.height > 2) { #ifdef BL_OUTPUT_DEBUG_INFO if (range == 400) cv::rectangle(drowDebugDetectLR, roiRect, cv::Scalar(0, 0, 255)); else cv::rectangle(drowDebugDetectLR, roiRect, cv::Scalar(0, 255, 255)); #endif //选取roi cv::Mat roi = img(roiRect).clone(); cv::GaussianBlur(roi, roi, cv::Size(5, 5), 0, 0); //竖直投影 cv::Mat roirow; cv::reduce(roi, roirow, 0, CV_REDUCE_AVG); if (scanLeft2right) { for (int j = 0; j < roirow.cols; j++) { int count = 0; for (int i = j; i < roirow.cols; i++) { if (roirow.ptr<uchar>(0)[i] >= THRESHOD) count++; else if (i != j) { j = i - 1; break; } else break; if (count > ContinuePointCount) { return (j + roiRect.x); } } } } else { for (int j = roirow.cols - 1; j >= 0; j--) { int count = 0; for (int i = j; i >= 0; i--) { if (roirow.ptr<uchar>(0)[i] >= THRESHOD) count++; else if (i != j) { j = i + 1; break; } else break; if (count > ContinuePointCount) { return (j + roiRect.x); } } } } } return -1; }
void CBrakeBeamPillarRoundPinDetector::DetectError(vector<SErrorInfoArray>& errorInfoArray, vector<Mat>& resultImageArray, /*vector<PositionOfComponents>& positionOfComponents,*/ int statues /*= 0*/) { //将车厢的方向统一(横向) flip(m_srcImageArray[0], m_srcImageArray[0], 1); flip(resultImageArray[1], resultImageArray[1], 1); for (int i = 0; i != m_srcImageArray.size(); ++i) { float maxMatchVal = -1.0; Point matchPoint; int templateIndex = 0; int brakeBeamPillarXPos = 0; int brakeBeamPillarYPos = 0; int middleBarLeftLine = FindMiddleBarLeftLine(i); if (!IsMiddlBarLeftLineInRange(middleBarLeftLine)) { SErrorInfoArray sei; sei.errorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.realErrorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.errorImageFile = m_srcImageFileArray[i]; if (i == 0) { sei.leftPos = 300; sei.rightPos = 600; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } else { sei.leftPos = 800; sei.rightPos = 1150; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } sei.confidence = 59; sei.errorImageIndex = m_interstedIndex[i]; errorInfoArray.push_back(sei); continue; } else { brakeBeamPillarXPos = middleBarLeftLine + 150; int brakeBeamClampYPos = FindBrakeBeamClampYPos(middleBarLeftLine, i); if (IsBrakeBeamClampYPosInRange(brakeBeamClampYPos)) { brakeBeamPillarYPos = brakeBeamClampYPos - 25; } else { SErrorInfoArray sei; sei.errorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.realErrorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.errorImageFile = m_srcImageFileArray[i]; if (i == 0) { sei.leftPos = 300; sei.rightPos = 600; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } else { sei.leftPos = 800; sei.rightPos = 1150; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } sei.confidence = 59; sei.errorImageIndex = m_interstedIndex[i]; errorInfoArray.push_back(sei); continue; } } Rect roiRect(brakeBeamPillarXPos, brakeBeamPillarYPos-100, 150, 350); for (int j = 0; j != m_templateImageArray.size(); ++j) { Mat compareResult; //匹配结果矩阵 //定义查找夹扣的ROI Mat searchBrakeBeamClamp_ROI = m_srcImageArray[i](roiRect).clone(); compareResult.create(searchBrakeBeamClamp_ROI.rows - m_templateImageArray[j].rows + 1, searchBrakeBeamClamp_ROI.cols - m_templateImageArray[j].cols + 1, CV_32FC1); matchTemplate(searchBrakeBeamClamp_ROI, m_templateImageArray[j], compareResult, CV_TM_CCOEFF_NORMED); //模板匹配 double minVal,maxVal; //矩阵中最小值,最大值 Point minLoc; //最小值的坐标 Point matchLoc; //最匹配值的坐标 minMaxLoc(compareResult, &minVal, &maxVal, &minLoc, &matchLoc, cv::Mat()); //寻找最匹配的点 if (maxVal > maxMatchVal) { maxMatchVal = maxVal; matchPoint.x = matchLoc.x + roiRect.x; matchPoint.y = matchLoc.y + roiRect.y; templateIndex = j; } } if (maxMatchVal <= 0.55 && maxMatchVal > 0.52) { SErrorInfoArray sei; sei.errorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.errorImageFile = m_srcImageFileArray[i]; if (i == 0) { sei.leftPos = 300; sei.rightPos = 600; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } else { sei.leftPos = 800; sei.rightPos = 1150; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } sei.confidence = 50; sei.errorImageIndex = m_interstedIndex[i]; errorInfoArray.push_back(sei); } else if(maxMatchVal <= 0.52) { SErrorInfoArray sei; sei.errorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.realErrorMask |= DEMO_ERROR_BRAKE_BEAM_PILLAR_ROUND_PIN_LOST; sei.errorImageFile = m_srcImageFileArray[i]; if (i == 0) { sei.leftPos = 300; sei.rightPos = 600; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } else { sei.leftPos = 800; sei.rightPos = 1150; sei.topPos = 300; sei.bottomPos = 650; rectangle(resultImageArray[m_interstedIndex[i]], Point(800,300),Point(1150,650),Scalar(0,0,255),2); } sei.confidence = 59; sei.errorImageIndex = m_interstedIndex[i]; errorInfoArray.push_back(sei); } } //将方向调回原来的方向 flip(m_srcImageArray[0], m_srcImageArray[0], 1); flip(resultImageArray[1], resultImageArray[1], 1); }
//探测故障 void CInTheBarCotterPinBreakOffDetector::DetectError(vector<SErrorInfoArray>& errorInfoArray, vector<Mat>& resultImageArray, /*vector<PositionOfComponents>& positionOfComponents,*/ int statues /*= 0*/) { //将车厢的方向统一 flip(m_srcImageArray[0], m_srcImageArray[0], 1); flip(resultImageArray[1], resultImageArray[1], 1); for (int i = 0; i != m_srcImageArray.size(); ++i) { float maxMatchVal = -1.0; Point matchPoint; int templateIndex = 0; int middleBarLeftLine = 0; //中间杆左边缘 int TruckDeadLeverTopLine = -1; //中拉杆上边缘 middleBarLeftLine = FindMiddleBarLeftLine(i); //获得中间杆的左边缘 if (IsMiddlBarLeftLineInRange(middleBarLeftLine)) { TruckDeadLeverTopLine = FindTruckDeadLeverTopLine(i, middleBarLeftLine); //获得中拉杆上边缘 } if (TruckDeadLeverTopLine == -1) { SErrorInfoArray sei; sei.errorMask |= DEMO_ERROR_PULL_ROD_IN_THE_COTTER_BREAKOFF; sei.errorImageFile = m_srcImageFileArray[i]; switch (i) { case 0: sei.leftPos = 300; sei.rightPos = 1000; sei.topPos = 250; sei.bottomPos = 750; break; case 1: sei.leftPos = 300; sei.rightPos = 1000; sei.topPos = 250; sei.bottomPos = 750; break; } sei.confidence = 52; sei.errorImageIndex = m_interstedIndex[i]; errorInfoArray.push_back(sei); rectangle(resultImageArray[m_interstedIndex[i]], Point(300,250),Point(1000,700),Scalar(0,0,255),2); continue; } else { for (int j = 0; j != m_templateImageArray.size(); ++j) { if (!IsValidRect(middleBarLeftLine + 80, TruckDeadLeverTopLine - 80, 400, 200)) { continue; } if (!IsValidRectInMat(m_srcImageArray[i], Rect(middleBarLeftLine + 80, TruckDeadLeverTopLine - 80, 400, 200))) { continue; } Rect roiRect(middleBarLeftLine + 80, TruckDeadLeverTopLine - 80, 400, 200); Mat compareResult; //匹配结果矩阵 //定义查找夹扣的ROI Mat searchBrakeBeamClamp_ROI = m_srcImageArray[i](roiRect); compareResult.create(searchBrakeBeamClamp_ROI.rows - m_templateImageArray[j].rows + 1, searchBrakeBeamClamp_ROI.cols - m_templateImageArray[j].cols + 1, CV_32FC1); matchTemplate(searchBrakeBeamClamp_ROI, m_templateImageArray[j], compareResult, CV_TM_CCOEFF_NORMED); //模板匹配 double minVal,maxVal; //矩阵中最小值,最大值 Point minLoc; //最小值的坐标 Point matchLoc; //最匹配值的坐标 minMaxLoc(compareResult, &minVal, &maxVal, &minLoc, &matchLoc, cv::Mat()); //寻找最匹配的点 if (maxVal > maxMatchVal) { maxMatchVal = maxVal; matchPoint.x = matchLoc.x + roiRect.x; matchPoint.y = matchLoc.y + roiRect.y; templateIndex = j; } } Rect roiRect(matchPoint.x, matchPoint.y, m_templateImageArray[templateIndex].cols, m_templateImageArray[templateIndex].rows); Ptr<FeatureDetector> detector = FeatureDetector::create( "SIFT" );//创建SIFT特征检测器 Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建特征向量生成器 if( detector.empty() || descriptor_extractor.empty() ) { return; } Mat roiMat = m_srcImageArray[i](roiRect).clone(); vector<KeyPoint> keypoints; detector->detect(roiMat,keypoints); Mat descriptor; descriptor_extractor->compute(roiMat,keypoints,descriptor); Mat featureVec(1, 20*128, CV_32FC1); if (descriptor.rows >= 20) { for (int j = 0; j != 20; ++j) { for (int k = 0; k != descriptor.cols; ++k) { featureVec.at<float>(j*128+k) = descriptor.at<float>(j,k); } } } else { for (int j = 0; j != descriptor.rows; ++j) { for (int k = 0; k != descriptor.cols; ++k) { featureVec.at<float>(j*128+k) = descriptor.at<float>(j,k); } } for (int j = descriptor.rows; j != 20; ++j) { for (int k = 0; k != descriptor.cols; ++k) { featureVec.at<float>(j*128+k) = -1; } } } float flag = m_nbc.predict(featureVec); //进行预测 if(flag == -1) { SErrorInfoArray sei; sei.errorMask |= DEMO_ERROR_PULL_ROD_IN_THE_COTTER_BREAKOFF; sei.errorImageFile = m_srcImageFileArray[i]; switch (i) { case 0: sei.leftPos = 300; sei.rightPos = 1000; sei.topPos = 250; sei.bottomPos = 750; break; case 1: sei.leftPos = 300; sei.rightPos = 1000; sei.topPos = 250; sei.bottomPos = 750; break; } sei.confidence = 52; sei.errorImageIndex = m_interstedIndex[i]; rectangle(resultImageArray[m_interstedIndex[i]], Point(300,250),Point(1000,700),Scalar(0,0,255),2); errorInfoArray.push_back(sei); continue; } } } flip(m_srcImageArray[0], m_srcImageArray[0], 1); flip(resultImageArray[1], resultImageArray[1], 1); }