## 工业视觉检测项目的算法实现

1、左侧大螺丝

       screwMat[i] = src(cv::Rect(screwLocation[i], screwSize[i]));
vector<KeyPoint> keypoints;
detector->detect(screwMat[i], keypoints);
if (keypoints.size() == 0) {
Mat gray; Mat bin;
vector<Vec3f> vec3f_method_hough;
cvtColor(screwMat[i], gray, COLOR_BGR2GRAY);
threshold(gray, bin, 100, 255, THRESH_OTSU);
if (vec3f_method_hough.size() >= 1)
putText(draw, "Y1", screwLocation[i], FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(255, 0, 0), 7);
else
{
//当探测到 ERROR的时候推出循环
putText(draw, "E1", screwLocation[i], FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 255, 0), 7);
bError = true;
}
vec3f_method_hough.clear();

2、左侧大螺丝防护罩

    //识别螺丝防护罩
coverMat[i] = src(Rect(coverLocation[i], coverSize[i]));
cvtColor(coverMat[i], tmpCoverMat[i], COLOR_BGR2GRAY);
threshold(tmpCoverMat[i], tmpCoverMat[i], 100, 255, THRESH_BINARY);
//取中间一列的投影
Mat tmp = tmpCoverMat[i].col(tmpCoverMat[i].cols / 2);
int istart = 0; int  iend = tmp.rows - 1;
//开头
for (int irow = 0; irow < tmp.rows - 3; irow++)
{
if (0 == tmp.at<uchar>(irow, 0) && tmp.at<uchar>(irow + 1, 0) > 0 && tmp.at<uchar>(irow + 2, 0) > 0 && tmp.at<uchar>(irow + 3, 0) > 0)
{
istart = irow;
break;
}
}
//结尾
for (int irow = tmp.rows - 1; irow > 4; irow--)
{
if (0 == tmp.at<uchar>(irow, 0) && tmp.at<uchar>(irow - 1, 0) > 0 && tmp.at<uchar>(irow - 2, 0) > 0 && tmp.at<uchar>(irow - 3, 0) > 0)
{
iend = irow;
break;
}
}
if (istart <= tmp.rows * 0.1 || iend >= tmp.rows*0.92)//注意这里的0.1和0.9可能是需要设置的
{
putText(draw, "N2", cv::Point(coverLocation[i].x + 150, coverLocation[i].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 0, 255), 7);
}

3、白色隔弧板

//在正确的基础上，进一步识别白色隔弧板
wbMat[i] = src(Rect(whiteBoardLocation[i], whiteBoardSize[i]));
cvtColor(wbMat[i], wbMat[i], COLOR_BGR2GRAY);
threshold(wbMat[i], wbTmpMat[i], 50, 255, THRESH_OTSU);
//1、去沾粘；
cv::rectangle(wbTmpMat[i], cv::Rect(0, 0, wbTmpMat[i].cols, wbTmpMat[i].rows), cv::Scalar(0),3);
Mat element = getStructuringElement(MORPH_ELLIPSE, Size(7, 3));
morphologyEx(wbTmpMat[i], wbTmpMat[i], cv::MORPH_OPEN, element);
//2、分轮廓
cv::Mat binDraw;
int iRight = 0;
vector<VP> binVP =  connection2(wbTmpMat[i], binDraw);
//3、以面积等特征筛选
for (int indexBindVP=0;indexBindVP<binVP.size();indexBindVP++)
{
double dArea =  cv::contourArea(binVP[indexBindVP]);
if (dArea >= 250 && dArea <= 480)//可能区间
iRight++;
//printf("%d__%f\n", indexBindVP, (float)dArea);
}

4、手柄

Mat handleMat = src(Rect(946, 884, 541, 378));
Mat handleTmp;
cvtColor(handleMat, handleTmp, COLOR_BGR2GRAY);
threshold(handleTmp, handleTmp, 100, 255, THRESH_OTSU);
cv::dilate(handleTmp, handleTmp, Mat());
Mat handleTmpRow = handleTmp.row(handleTmp.rows / 2);
int iHandleStart = 0; int  iHandleEnd = handleTmpRow.cols - 1;
int iHandleUp = 0;
//开头
for (int i = 0; i < handleTmpRow.cols - 2; i++)
{
if (0 == handleTmpRow.at<uchar>(0, i) && handleTmpRow.at<uchar>(0, i + 1) > 0 && handleTmpRow.at<uchar>(0, i + 2) > 0)
iHandleUp++;
}
if (iHandleUp > 7)//超级参数
{
putText(draw, "N4", cv::Point(946 + 150, 884), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 0, 255), 7);
}
else {
putText(draw, "Y4", cv::Point(946 + 150, 884), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(255, 0, 0), 7);
}

5、隔膜

//识别隔膜
filmMat[i] = src(Rect(filmLocation[i], filmSize[i]));
cv::rectangle(draw, Rect(filmLocation[i], filmSize[i]), cv::Scalar(0, 0, 255));
cv::cvtColor(filmMat[i], filmMat[i], COLOR_BGR2GRAY);
cv::threshold(filmMat[i], tmpFilmMat[i], 100, 255, cv::THRESH_OTSU);
cv::dilate(tmpFilmMat[i], tmpFilmMat[i], cv::Mat());
//1、去粘连
cv::rectangle(tmpFilmMat[i], cv::Rect(0, 0, tmpFilmMat[i].cols, tmpFilmMat[i].rows), Scalar(0));
//2、找最大轮廓
vector<cv::Point> biggestContour = FindBigestContour(tmpFilmMat[i]);
Rect boundRect = boundingRect(Mat(biggestContour)); //获得轮廓最小外接矩形
cv::rectangle(draw,cv::Rect(filmLocation[i].x+boundRect.x, filmLocation[i].y+boundRect.y, boundRect.width, boundRect.height), cv::Scalar(0, 255, 0));
//3、进行判断
float fScale = (float)boundRect.width / (float)filmSize[i].width;
if (fScale >= 0.65 && boundRect.x>=8)
{
putText(draw, "Y5", cv::Point(filmLocation[i].x + 150, filmLocation[i].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(255, 0, 0), 7);
}
else
{
putText(draw, "N5", cv::Point(filmLocation[i].x + 150, filmLocation[i].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 0, 255), 7);
}
6、小螺丝

     littleScrewMat[i] = src(Rect(LittleScrewLocation[i], LittleScrewSize[i]));
cvtColor(littleScrewMat[i], tmpLittleMat[i], COLOR_BGR2GRAY);
threshold(tmpLittleMat[i], tmpLittleMat[i], 100, 255, THRESH_BINARY);
//取一列的投影
Mat tmp = tmpLittleMat[i].col(tmpLittleMat[i].cols * 0.7);
int iLittleScrewMat = 0;
for (int i = 0; i < tmp.rows - 2; i++)
{
if (0 == tmp.at<uchar>(i, 0) && tmp.at<uchar>(i + 1, 0) > 0 && tmp.at<uchar>(i + 2, 0) > 0)
iLittleScrewMat++;
}
if (iLittleScrewMat <= 0)//超级参数
{
putText(draw, "N6", cv::Point(LittleScrewLocation[i].x + 150, LittleScrewLocation[i].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 0, 255), 7);
}
else {
……
}
7、小螺丝红漆

     littleScrewMat[i] = src(Rect(LittleScrewLocation[i], LittleScrewSize[i]));
cvtColor(littleScrewMat[i], tmpLittleMat[i], COLOR_BGR2GRAY);
threshold(tmpLittleMat[i], tmpLittleMat[i], 100, 255, THRESH_BINARY);
//取一列的投影
Mat tmp = tmpLittleMat[i].col(tmpLittleMat[i].cols * 0.7);
int iLittleScrewMat = 0;
for (int i = 0; i < tmp.rows - 2; i++)
{
if (0 == tmp.at<uchar>(i, 0) && tmp.at<uchar>(i + 1, 0) > 0 && tmp.at<uchar>(i + 2, 0) > 0)
iLittleScrewMat++;
}
if (iLittleScrewMat <= 0)//超级参数
{
putText(draw, "N6", cv::Point(LittleScrewLocation[i].x + 150, LittleScrewLocation[i].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 0, 255), 7);
}
else {
……
}

8、黑色隔弧板

bbMat[i] = src(Rect(blackBoardLocation[i], blackBoardSize[i]));
cvtColor(bbMat[i], bbTmpMat[i], COLOR_BGR2GRAY);
threshold(bbTmpMat[i], bbTmpMat[i], 100, 255, cv::THRESH_OTSU);
bitwise_not(bbTmpMat[i], bbTmpMat[i]);
//1、投影分析
Mat tmp = bbTmpMat[i].row(bbTmpMat[i].rows/2);
int ibbMat = 0;
for (int i = 0; i < tmp.cols - 2; i++)
{
if (0 == tmp.at<uchar>(0,i) && tmp.at<uchar>(0,i + 1) > 0 && tmp.at<uchar>(0,i + 2) > 0)
ibbMat++;
}
9、右侧大螺丝

10、灭弧室板

cutMat[icutMat] = src(Rect(cutLocation[icutMat], cutSize[icutMat]));
cvtColor(cutMat[icutMat], cutTmpMat[icutMat], COLOR_BGR2GRAY);
threshold(cutTmpMat[icutMat], cutTmpMat[icutMat], 100, 255, cv::THRESH_OTSU);
bitwise_not(cutTmpMat[icutMat], cutTmpMat[icutMat]);
vector<VP> vpTmpMat= connection2(cutTmpMat[icutMat]);
//printf("vp size is%d\n", vpTmpMat.size());
//补充一个投影
tmpCutRow[icutMat] = cutTmpMat[icutMat].row(cutTmpMat[icutMat].rows * 0.7);
int iCut = 0;
for (int icutTmpMat = 0; icutTmpMat < tmpCutRow[icutMat].cols - 1; icutTmpMat++)
{
if ( tmpCutRow[icutMat].at<uchar>(0, icutTmpMat)>0 && 0 == tmpCutRow[icutMat].at<uchar>(0, icutTmpMat + 1) )
iCut++;
}
if (vpTmpMat.size() < 11 && iCut < 3)
{
putText(draw, "N10", cv::Point(cutLocation[icutMat].x + 150, cutLocation[icutMat].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(0, 0, 255), 7);
}
else
{
putText(draw, "Y10", cv::Point(cutLocation[icutMat].x + 150, cutLocation[icutMat].y), FONT_HERSHEY_SIMPLEX, 3.0f, CV_RGB(255, 0, 0), 7);
}

posted on 2022-12-22 11:13  jsxyhelu  阅读(152)  评论(0编辑  收藏  举报