cv::Mat CVImgProc::GetHistgramImg(const cv::Mat &imgSrc/*, int indexChannel*/) { int channels[1]={0}; channels[0] = 0;// indexChannel;//使用通道号 int histSize[1]={256};//项的数量 float hranges[2]={0.0,255.0};//像素的最小和最大值 const float *ranges[1]; ranges[0]=hranges; cv::MatND hist;//计算图像直方图 cv::calcHist(&imgSrc,1,channels,cv::Mat(),hist,1,histSize,ranges); double maxVal=0; double minVal=0; cv::minMaxLoc(hist,&minVal,&maxVal,0,0); int W_HistImg = histSize[0]*4; int H_HistImg = histSize[0]*3; cv::Mat imgHist(H_HistImg,W_HistImg,CV_8UC3,cv::Scalar::all(255)); int hpt = static_cast<int>(0.9*H_HistImg);//设置最高点 int xUnitLen = static_cast<int>(W_HistImg/histSize[0]);//X轴单位长度 int xPt=0; //每个条目都绘制一条垂直线 for(int n=0;n<histSize[0];n++) { float binVal = hist.at<float>(n); int intensity = static_cast<int>(binVal*hpt/maxVal); cv::line(imgHist, cv::Point(xPt,H_HistImg), cv::Point(xPt,H_HistImg-intensity), cv::Scalar(0,255,0));//cv::Scalar::all(0) //画x轴刻度 if(n%16 == 0) { cv::rectangle(imgHist, cv::Point(xPt,H_HistImg), cv::Point(xPt+5,H_HistImg-5), cv::Scalar(0,0,255)); } xPt += xUnitLen; } return imgHist; }
int main() { cv::VideoCapture camera(0); assert( camera.isOpened() ); cv::CascadeClassifier faceCascade; assert( faceCascade.load("haarcascades/haarcascade_frontalface_alt.xml") ); cv::CascadeClassifier eyeCascade; assert( eyeCascade.load("haarcascades/haarcascade_mcs_eyepair_big.xml") ); cv::Mat frame, image, faceImage, eyeImage, rightEyeImage, leftEyeImage; cv::namedWindow( WINDOW_NAME, 1 ); std::vector<cv::Rect> objects; IntVec vHist, hHist, rightHorizHist, rightVertHist, leftHorizHist, leftVertHist; cv::Rect faceRect, eyeRect, leftEye, rightEye; float faceModX, faceModY, eyeModX, eyeModY; int eyeCut; camera >> frame; faceModX = frame.cols / FACE_SEARCH_WIDTH; faceModY = frame.rows / FACE_SEARCH_HEIGHT; do { camera >> frame; cv::resize(frame, image, cv::Size(FACE_SEARCH_WIDTH, FACE_SEARCH_HEIGHT)); faceCascade.detectMultiScale(image, objects); if ( objects.size() ) { faceRect = objects[0]; faceRect.x *= faceModX; faceRect.y *= faceModY; faceRect.height *= faceModY; faceRect.width *= faceModX; cv::rectangle(frame, faceRect, CV_RGB(255, 0, 0)); rectSubImg(frame, faceImage, faceRect); cv::resize(faceImage, faceImage, cv::Size(faceRect.width / 2, faceRect.height / 2)); eyeCascade.detectMultiScale(faceImage, objects); if ( objects.size() ) { eyeRect = objects[0]; eyeRect.x *= 2; eyeRect.y *= 2; eyeRect.height *= 2; eyeRect.width *= 2; eyeRect.x += faceRect.x; eyeRect.y += faceRect.y; splitEyeRect(eyeRect, leftEye, rightEye); cv::rectangle(frame, leftEye, CV_RGB(255, 255, 0)); cv::rectangle(frame, rightEye, CV_RGB(255, 255, 0)); rectSubImg(frame, rightEyeImage, rightEye); rectSubImg(frame, leftEyeImage, leftEye); imgHist(rightEyeImage, rightHorizHist, rightVertHist); imgHist(leftEyeImage, leftHorizHist, leftVertHist); smoothHist(rightHorizHist, 50); smoothHist(rightVertHist, 50); smoothHist(leftHorizHist, 50); smoothHist(leftVertHist, 50); drawHist(frame, rightHorizHist, cv::Point(rightEye.x, rightEye.y), RIGHT, UP, 50); drawHist(frame, rightVertHist, cv::Point(rightEye.x + rightEye.width, rightEye.y), DOWN, RIGHT, 50); drawHist(frame, leftHorizHist, cv::Point(leftEye.x, leftEye.y), RIGHT, UP, 50); drawHist(frame, leftVertHist, cv::Point(leftEye.x, leftEye.y), DOWN, LEFT, 50); //FIXME move to functions for(int i = 1; i < rightHorizHist.size() - 1; i ++) { if (rightHorizHist[i] <= rightHorizHist[i-1] && rightHorizHist[i] <= rightHorizHist[i+1]) { cv::line(frame, cv::Point(rightEye.x + i, rightEye.y), cv::Point(rightEye.x + i, rightEye.y + rightEye.height), CV_RGB(255, 0, 0)); } } for(int i = 1; i < leftHorizHist.size() - 1; i ++) { if (leftHorizHist[i] <= leftHorizHist[i-1] && leftHorizHist[i] <= leftHorizHist[i+1]) { cv::line(frame, cv::Point(leftEye.x + i, leftEye.y), cv::Point(leftEye.x + i, leftEye.y + leftEye.height), CV_RGB(255, 0, 0)); } } for(int i = 1; i < rightVertHist.size() - 1; i ++) { if (rightVertHist[i] <= rightVertHist[i-1] && rightVertHist[i] <= rightVertHist[i+1]) { cv::line(frame, cv::Point(rightEye.x, rightEye.y + i), cv::Point(rightEye.x + rightEye.width, rightEye.y + i), CV_RGB(255, 0, 0)); } } for(int i = 1; i < leftVertHist.size() - 1; i ++) { if (leftVertHist[i] <= leftVertHist[i-1] && leftVertHist[i] <= leftVertHist[i+1]) { cv::line(frame, cv::Point(leftEye.x, leftEye.y + i), cv::Point(leftEye.x + leftEye.width, leftEye.y + i), CV_RGB(255, 0, 0)); } } } } cv::imshow( WINDOW_NAME, frame); } while (cv::waitKey(10) != 27); return 0; }