Esempio n. 1
0
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);
}