前篇讲过基于相机焦距和手机PPI进行测量身高,但是这种测量方式具有不可控性,误差很大,所以该篇文章采用参照物对比进行测量身高。
和前篇一样进行HOG特征检测,Grabcut分割,BorderMatting边缘细化。
然后就是识别参照物,利用直方图均衡化提高对比度然后在进行剔除非阈值范围内的颜色。当然在进行处理之前,将RGB模型转变成HSV模型。该项目是基于小程序实现,所以用户再输入基本信息时需要输入参照物的长度和颜色。
void GCApplication::measureReferencePX() { Mat imgHSV; //黄、红、蓝 int index; if (color == "黄色") index = 0; else if (color == "红色") index = 1; else index = 2; int iLowH[3] = { 18,156,110 }; int iHighH[3] = { 38,180,130 }; //设置饱和度的范围值 int iLowS[3] = { 90,43,43 }; int iHighS = 255; //设置亮度的范围值 int iLowV[3] = { 90,46 ,46 }; int iHighV = 255; vector<Mat> hsvSplit; cvtColor(*image, imgHSV, COLOR_BGR2HSV); //BGR 转化成 HSV,因为直方图均衡化需要在HSV空间做 imshow("imgHSV1", imgHSV); split(imgHSV, hsvSplit); equalizeHist(hsvSplit[2], hsvSplit[2]); merge(hsvSplit, imgHSV); inRange(imgHSV, Scalar(iLowH[index], iLowS[index], iLowV[index]), Scalar(iHighH[index], iHighS, iHighV), imgThresholded); //图像的范围 imshow("Thresholded", imgThresholded); //开操作 (去除一些噪点) Mat element = getStructuringElement(MORPH_RECT, Size(5, 5)); //morphologyEx(imgThresholded, imgThresholded, MORPH_OPEN, element); //闭操作 (连接一些连通域) morphologyEx(imgThresholded, imgThresholded, MORPH_CLOSE, element); //计算参照物像素高度 int i, j; int flagA, flagB; flagA = flagB = 0; //从上面进行遍历 for (i = 0; i < imgThresholded.rows; i++) { for (j = 0; j < imgThresholded.cols; j++) if (imgThresholded.at<uchar>(i, j) == 255 && !flagA) // 标记第一个出现像素的像素点 { FA.x = j;//注意顺序,坐标原点位于左上角 FA.y = i; flagA = 1; break; } if (flagA) break; } //从下面进行遍历 for (i = imgThresholded.rows - 1; i > 0; i--) { for (j = 0; j < imgThresholded.cols; j++) if (imgThresholded.at<uchar>(i, j) == 255 && !flagB) // 标记第一个出现像素的像素点 { FB.x = j;//注意顺序,坐标原点位于左上角 FB.y = i; flagB = 1; break; } if (flagB) break; } imshow("Thresholded Image", imgThresholded); maxRefPX = FB.y - FA.y; }
然后也对人物前景进行二值化,遍历找到两组特征点。
计算两个的比例系数K,然后根据参照物真实长度进行等比例计算。
经过系统的测试,如在系统的使用要求下(拍摄距离需2.5m外,测量人员身上携带颜色与参照物颜色不同),误差率在5‰。