开发环境
开发环境
- 64 bits Windows OS (Win8.1)
- VS2013
- OpenCV 2.4.9
功能原理
算法要求
完成将Camera拍摄的手掌图片中分割出每个手指用于指纹识别
算法流程
核心代码
#ifdef TIME_RUN_COST
double duration = static_cast(cv::getTickCount());//time
#endif
cout << "filename=" << filename < IplImage
IplImage* pImgOutEqualizeHist = EqualizeHistColorImage(&pImgInEqualizeHist);
matOutEqualizeHist = pImgOutEqualizeHist; //IplImage -> Mat
#endif
// out
Mat imgSrc = Mat(imgCut.size(), CV_8UC1);
imgCut.copyTo(imgSrc);
Mat imgContour = Mat(imgSrc.size(), CV_8UC1);
#ifdef FINGER_EXTRACT_AT_NIGHT
cout << "Nigth,Threshold..." << endl;
Mat imgTmp;// = Mat(imgCut.size(), CV_8UC1);
cvtColor(imgSrc, imgTmp, CV_RGB2GRAY);
cvThresholdOtsu(&((IplImage)imgTmp), &((IplImage)imgTmp));
imgTmp.copyTo(imgContour);
#else
cout << "Day,Skin..." << endl;
Mat imgSkin2 = Mat(imgSrc.size(), CV_8UC1);
IplImage* pImgSkin2 = cvCreateImage(cvSize(imgSrc.cols, imgSrc.rows), IPL_DEPTH_8U, 1);
IplImage pImg2 = (IplImage)(imgSrc); // Mat-> IplImage
cvSkinOtsu(&pImg2, pImgSkin2);
imgSkin2 = pImgSkin2; //IplImage -> Mat
//Mat imgSkin = Mat(imgSrc.size(), CV_8UC1);
imgSkin2.copyTo(imgContour);
#endif
/////////////////////// Contours
cout << "Find Contours..." << endl;
vector > contours;
vector hierarchy;
findContours(imgContour, contours, hierarchy,
CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
sort(contours.begin(), contours.end(), compareContourAreas);
int contours_num = contours.size();
cout << "contours_num=" << contours_num << endl;
#if 0
vector>::const_iterator itContours = contours.begin();
//for (int i = 0; i < contours.size(); i++)
for (; itContours != contours.end(); ++itContours)
{
cout << "Size: " << itContours->size() << endl;//每个轮廓包含的点数
}
#endif
#if 1 //usd
// Eliminate too short or too long contours
int cmin = 100; // minimum contour length
//int cmax= 1000; // maximum contour length
vector>::const_iterator itc = contours.begin();
while (itc != contours.end())
{
//if (itc->size() < cmin || itc->size() > cmax)
if (itc->size() < cmin) {
itc = contours.erase(itc);
}
else
++itc;
}
contours_num = contours.size();
cout << endl << "contours_num after Eliminate=" << contours_num << endl;
#endif
// extract the contour img
cout << "Extract Contours..." << endl;
if (contours_num >= 4)
{
Mat img1, img2, img3, img4;
std::vector biggest1Contour = contours[contours_num - 1];
std::vector biggest2Contour = contours[contours_num - 2];
std::vector biggest3Contour = contours[contours_num - 3];
std::vector biggest4Contour = contours[contours_num - 4];
std::vector smallestContour = contours[0];
extractFingerImg2(contours, imgSrc, img1, contours_num, 1);
extractFingerImg2(contours, imgSrc, img2, contours_num, 2);
extractFingerImg2(contours, imgSrc, img3, contours_num, 3);
extractFingerImg2(contours, imgSrc, img4, contours_num, 4);
}
else if (contours_num == 3)
{
Mat img1, img2, img3;
std::vector biggest1Contour = contours[contours_num - 1];
std::vector biggest2Contour = contours[contours_num - 2];
std::vector biggest3Contour = contours[contours_num - 3];
std::vector smallestContour = contours[0];
extractFingerImg2(contours, imgSrc, img1, contours_num, 1);
extractFingerImg2(contours, imgSrc, img2, contours_num, 2);
extractFingerImg2(contours, imgSrc, img3, contours_num, 3);
}
else if (contours_num == 2)
{
Mat img1, img2;
std::vector biggest1Contour = contours[contours_num - 1];
std::vector biggest2Contour = contours[contours_num - 2];
std::vector smallestContour = contours[0];
extractFingerImg2(contours, imgSrc, img1, contours_num, 1);
extractFingerImg2(contours, imgSrc, img2, contours_num, 2);
}
else if (contours_num == 1)
{
Mat img1;
std::vector biggest1Contour = contours[contours_num - 1];
std::vector smallestContour = contours[0];
extractFingerImg2(contours, imgSrc, img1, contours_num, 1);
}
else
{
cout << "error" << endl;
}
#ifdef TIME_RUN_COST
duration = static_cast(cv::getTickCount()) - duration;
duration /= cv::getTickFrequency(); // the elapsed time in ms
cout << "time cost=" << duration << "s"<
算法效果
白天复杂场景
晚上场景
批量测试场景
By SkySeraph-2014
合作联系:skyseraph00@163.com
————————
版权声明
SkySeraph by SkySeraph is licensed under a Creative Commons BY-NC-ND 4.0 International License.
由Bob创作并维护的SkySeraph博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证.
本文首发于SkySeraph博客( skyseraph.com ),版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
微信扫码打赏SkySeraph
如果您愿意捐助其它金额请戳我~~,扫码支付宝/微信
本文永久链接:skyseraph.com/2014/07/24/…