void GetProbabilities( const HeadPoseParticleEvalBase& eval_base, int x, int y, int s, std::map<int, double>& probabilities ) { cv::Rect_<int> roi_rect( x - eval_base.offset_x(), y - eval_base.offset_y(), s, s ); cv::Mat roi_image = eval_base.image()( roi_rect ); classifier_.PredictProbability( roi_image, probabilities ); }
int main (int argc, char **argv) { cv::Mat input,mask_img,not_masked; //loading haar classifier std::string cascadeName = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"; cv::CascadeClassifier cascade; if(!cascade.load(cascadeName)){ printf("ERROR: cascadefile見つからん!\n"); return -1; } //loading resource file(for face) input=cv::imread("/Users/naoto/git/opencv_gl/opencv/minematsu1.png",1); if(input.empty()){ printf("ERROR: image not found!\n"); return 0; } double scale = 4.0; cv::Mat gray, smallImg(cv::saturate_cast<int>(input.rows/scale),cv::saturate_cast<int>(input.cols/scale),CV_8UC1); cv::cvtColor(input, gray, CV_BGR2GRAY); cv::resize(gray, smallImg, smallImg.size(),0,0,cv::INTER_LINEAR); cv::equalizeHist(smallImg, smallImg);//ヒストグラムビンの合計値が 255 になるようヒストグラムを正規化 std::vector<cv::Rect> faces; cascade.detectMultiScale(smallImg, faces,1.1,2,CV_HAAR_SCALE_IMAGE,cv::Size(20,20)); int i; printf("deteced faces:%d\n",(int)faces.size()); for (i=0; i<faces.size(); i++) { cv::Point center,p1,p2; int radius; //saturate_castについては http://opencv.jp/opencv-2svn/cpp/operations_on_arrays.html center.x = cv::saturate_cast<int>((faces[i].x + faces[i].width*0.5)*scale);//scaleはここで戻していることに注意! center.y = cv::saturate_cast<int>((faces[i].y + faces[i].height*0.5)*scale); radius = cv::saturate_cast<int>((faces[i].width + faces[i].height)*0.25*scale); p1.x=center.x-radius;p1.y=center.y-radius; p2.x=center.x+radius;p2.y=center.y+radius; cv::Rect roi_rect(center.x-radius,center.y-radius,radius*2,radius*2);//左上のx座標,y座標,width,depthというふうに格納していく mask_img.create(input.size(), CV_8UC1); mask_img=cv::Scalar(0,0,0); not_masked=mask_img(roi_rect); not_masked=cv::Scalar(255,255,255); } cv::namedWindow("result",1); cv::namedWindow("masked",1); cv::imshow("result", input); cv::imshow("masked", mask_img); cv::waitKey(0); return 0; }
// allCandidates contains the previous positions, scaled to the original // dimension of image of the found face // thus we can exploit this thing to skip a big section of the level = the // intersection of the candidates // scaled by factor (thus is compatible with level) with level void FaceClassifier::_slidingSearch(cv::Mat1b& level, float factor, std::vector<cv::Rect>& allCandidates) { cv::Size winSize(std::ceil(_windowSize.width * factor), std::ceil(_windowSize.height * factor)); std::vector<cv::Rect> toSkip; for (const cv::Rect& r : allCandidates) { toSkip.push_back(cv::Rect(r.x / factor, r.y / factor, r.width / factor, r.height / factor)); } for (auto y = 0; y < level.rows - _windowSize.height; y += _step) { for (auto x = 0; x < level.cols - _windowSize.width; x += _step) { cv::Rect roi_rect(x, y, _windowSize.width, _windowSize.height); // if roi_rect intersect a toSkip element, lets continue auto exists = std::find_if(toSkip.begin(), toSkip.end(), [&](const cv::Rect& skip) { cv::Rect intersection(skip & roi_rect); if (intersection.area() > 0) { x += intersection.width + _step; return true; } return false; }); if (exists != toSkip.end()) { // intersection exists, we can skip continue; } cv::Mat1b roi = level(roi_rect); if (_vc->classify(roi)) { // variance // std::cout << "V"; if (_fc->classify(roi)) { // features (shape) // std::cout << "F"; if (_sc->classify(roi)) { // svm to refine // std::cout << "S"; cv::Rect destPos(std::floor(x * factor), std::floor(y * factor), winSize.width + 1, winSize.height + 1); allCandidates.push_back(destPos); // add current roi to toSkip vector toSkip.push_back(roi_rect); x += _windowSize.height; } } // std::cout << std::endl; } } } }
int main (int argc, char **argv) { std::string cascadeName = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"; cv::CascadeClassifier cascade; if(!cascade.load(cascadeName)){ printf("ERROR: cascadefile見つからん!\n"); return -1; } cv::Mat frame; cv::VideoCapture cap; cap.open(0); cap >> frame; cv::namedWindow("result",1); cv::createTrackbar("size", "result", &size_of_mosaic, 30,0); double scale = 4.0; cv::Mat gray, smallImg(cv::saturate_cast<int>(frame.rows/scale),cv::saturate_cast<int>(frame.cols/scale),CV_8UC1); for(;;){ cap >> frame; cv::cvtColor(frame, gray, CV_BGR2GRAY); cv::resize(gray, smallImg, smallImg.size(),0,0,cv::INTER_LINEAR); cv::equalizeHist(smallImg, smallImg); std::vector<cv::Rect> faces; cascade.detectMultiScale(smallImg, faces,1.1,3,CV_HAAR_SCALE_IMAGE,cv::Size(20,20)); int i; for (i=0; i<faces.size(); i++) { #if FLAG //use built-in function cv::Point center; int radius; center.x = cv::saturate_cast<int>((faces[i].x + faces[i].width*0.5)*scale); center.y = cv::saturate_cast<int>((faces[i].y + faces[i].height*0.5)*scale); radius = cv::saturate_cast<int>((faces[i].width + faces[i].height)*0.25*scale); if(size_of_mosaic < 1)size_of_mosaic=1; cv::Rect roi_rect(center.x-radius,center.y-radius,radius*2,radius*2); cv::Mat mosaic = frame(roi_rect); cv::Mat tmp = frame(roi_rect); cv::resize(mosaic, tmp, cv::Size(radius/size_of_mosaic,radius/size_of_mosaic),0,0); cv::resize(tmp, mosaic, cv::Size(radius*2,radius*2),0,0,CV_INTER_NN); #else //目元の辺りに線を引く cv::Point center; int radius; double eye_ratio=0.2;//顔の中心から半径何割のところに線を引くか center.x = cv::saturate_cast<int>((faces[i].x + faces[i].width*0.5)*scale); center.y = cv::saturate_cast<int>((faces[i].y + faces[i].height*0.5)*scale); radius = cv::saturate_cast<int>((faces[i].width + faces[i].height)*0.25*scale); cv::line(frame,cv::Point(center.x-radius,center.y-radius*eye_ratio),cv::Point(center.x-radius+radius*2,center.y-radius*eye_ratio) ,cv::Scalar(0),80,8,0); #endif } cv::imshow("result", frame); int key = cv::waitKey(10); if(key == 'q' || key == 'Q') break; } return 0; }
// usage: poisson.exe [source image (color)] [destination image (color] [mask image (gray)] [outout image (color] [offset y] [offset x] int main(int argc, char** argv){ int i; int offset[2]; IplImage *im_src = NULL, *im_dst = NULL, *im_mask = NULL; if(argc != 7){ fprintf(stderr,"usage: poisson.exe [source image (color)] [destination image (color)] [mask image (gray)] [outout image (color)] [offset y] [offset x]\n"); exit(0); } //////loading source image(cv::Mat input) & creating mask(cv::Mat mask_img) cv::Mat input,mask_img,not_masked; //loading haar classifier std::string cascadeName = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"; cv::CascadeClassifier cascade; if(!cascade.load(cascadeName)){ printf("ERROR: cascadefile見つからん!\n"); return -1; } //loading resource file(for face) input=cv::imread(argv[1],1); if(input.empty()){ printf("ERROR: image not found!\n"); return 0; } double scale = 4.0; cv::Mat gray, smallImg(cv::saturate_cast<int>(input.rows/scale),cv::saturate_cast<int>(input.cols/scale),CV_8UC1); cv::cvtColor(input, gray, CV_BGR2GRAY); cv::resize(gray, smallImg, smallImg.size(),0,0,cv::INTER_LINEAR); cv::equalizeHist(smallImg, smallImg);//ヒストグラムビンの合計値が 255 になるようヒストグラムを正規化 std::vector<cv::Rect> faces; cascade.detectMultiScale(smallImg, faces,1.1,2,CV_HAAR_SCALE_IMAGE,cv::Size(20,20)); int i; printf("deteced faces:%d\n",(int)faces.size()); for (i=0; i<faces.size(); i++) { cv::Point center; int radius; //saturate_castについては http://opencv.jp/opencv-2svn/cpp/operations_on_arrays.html center.x = cv::saturate_cast<int>((faces[i].x + faces[i].width*0.5)*scale);//scaleはここで戻していることに注意! center.y = cv::saturate_cast<int>((faces[i].y + faces[i].height*0.5)*scale); radius = cv::saturate_cast<int>((faces[i].width + faces[i].height)*0.25*scale); cv::Point p1,p2; p1.x=center.x-radius;p1.y=center.y-radius; p2.x=center.x+radius;p2.y=center.y+radius; cv::Rect roi_rect(center.x-radius,center.y-radius,radius*2,radius*2);//左上のx座標,y座標,width,depthというふうに格納していく mask_img.create(input.size(), CV_8UC1); mask_img=cv::Scalar(0,0,0); not_masked=mask_img(roi_rect); not_masked=cv::Scalar(255,255,255); } // for debug(checking masks) // cv::namedWindow("result",1); // cv::namedWindow("masked",1); // cv::imshow("result", input); // cv::imshow("masked", mask_img); // cv::waitKey(0); //loading destination image() & find position and size //resizing source image & calc offset if( (im_src = cvLoadImage( argv[1], CV_LOAD_IMAGE_COLOR)) == 0 ){ fprintf(stderr,"No such file %s", argv[1]); exit(0); } if( (im_dst = cvLoadImage( argv[2], CV_LOAD_IMAGE_COLOR)) == 0 ){ fprintf(stderr,"No such file %s", argv[2]); exit(0); } if( (im_mask = cvLoadImage( argv[3], CV_LOAD_IMAGE_GRAYSCALE)) == 0 ){ fprintf(stderr,"No such file %s", argv[3]); exit(0); } offset[0]=atoi(argv[5]); offset[1]=atoi(argv[6]); for(i=0;i<3;i++){// i:channnels quasi_poisson_solver(im_src, im_dst, im_mask, i, offset); //poisson_solver(im_src, im_dst, im_mask, i, offset); } cvSaveImage(argv[4],im_dst); cvReleaseImage(&im_src); cvReleaseImage(&im_dst); cvReleaseImage(&im_mask); return 0; }
int main(int argc, char *argv[]) { // 1. load classifier std::string cascadeName = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"; //Haar-like cv::CascadeClassifier cascade; if(!cascade.load(cascadeName)){ printf("ERROR: cascadeFile not found\n"); return -1; } // 2. initialize VideoCapture cv::Mat frame; cv::VideoCapture cap; cap.open(0); cap >> frame; // 3. prepare window and trackbar cv::namedWindow("result", 1); cv::createTrackbar("size", "result", &size_of_mosaic, 30, 0); double scale = 4.0; cv::Mat gray, smallImg(cv::saturate_cast<int>(frame.rows/scale), cv::saturate_cast<int>(frame.cols/scale), CV_8UC1); for(;;){ // 4. capture frame cap >> frame; //convert to gray scale cv::cvtColor( frame, gray, CV_BGR2GRAY ); // 5. scale-down the image cv::resize(gray, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR); cv::equalizeHist(smallImg, smallImg); // 6. detect face using Haar-classifier std::vector<cv::Rect> faces; ///multi-scale face searching // image, size, scale, num, flag, smallest rect cascade.detectMultiScale(smallImg, faces, 1.1, 2,//この引数を大きくすると検出が早くなる CV_HAAR_SCALE_IMAGE, cv::Size(30,30)); // 7. mosaic(pixelate) face-region //std::vector<cv::Rect>::const_iterator r = faces.begin(); //for(; r != faces.end(); ++r) { int i; for(i=0;i<faces.size();++i){ cv::Point center; int radius; center.x = cv::saturate_cast<int>((faces[i].x + faces[i].width*0.5)*scale); center.y = cv::saturate_cast<int>((faces[i].y + faces[i].height*0.5)*scale); radius = cv::saturate_cast<int>((faces[i].width + faces[i].height)*0.25*scale); //mosaic if(size_of_mosaic < 1) size_of_mosaic = 1; cv::Rect roi_rect(center.x-radius,center.y-radius,radius*2,radius*2); cv::Mat mosaic = frame(roi_rect); cv::Mat tmp; cv::resize(mosaic,tmp,cv::Size(radius / size_of_mosaic, radius / size_of_mosaic),0,0); cv::resize(tmp,mosaic, cv::Size(radius*2, radius*2),0,0,CV_INTER_NN); } // 8. show mosaiced image to window cv::imshow("result", frame ); int key = cv::waitKey(10); if(key == 'q' || key == 'Q') break; } return 0; }
// usage: poisson.exe [source image (color)] [destination image (color] [mask image (gray)] [outout image (color] [offset y] [offset x] int main(int argc, char** argv){ int offset[2]; IplImage *im_src =NULL, *im_dst = NULL, *im_mask = NULL; cv::Mat input,dst_img,mask_img,not_masked,mask_img_gray; if(argc != 4){ fprintf(stderr,"usage: poisson.exe [source image (color)] [destination image (color)] [outout image (color)] [offset y] [offset x]\n"); exit(0); } //////loading source image(cv::Mat input) & creating mask(cv::Mat mask_img) //loading haar classifier std::string cascadeName = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"; cv::CascadeClassifier cascade; if(!cascade.load(cascadeName)){ printf("ERROR: cascadefile見つからん!\n"); return -1; } //////loading destination image() & find position and size //loading destination file(for face) dst_img=cv::imread(argv[2],1); if(dst_img.empty()){ printf("ERROR:distination image not found!\n"); return 0; } //preprocessing double scale = 4.0; cv::Mat gray1, smallImg1(cv::saturate_cast<int>(dst_img.rows/scale),cv::saturate_cast<int>(dst_img.cols/scale),CV_8UC1); cv::cvtColor(dst_img, gray1, CV_BGR2GRAY); cv::resize(gray1, smallImg1, smallImg1.size(),0,0,cv::INTER_LINEAR); cv::equalizeHist(smallImg1, smallImg1);//ヒストグラムビンの合計値が 255 になるようヒストグラムを正規化 std::vector<cv::Rect> faces,faces1,faces2; cv::Point center2,center1; int radius,radius1,radius2; cv::Point p1,p2; //find face size cascade.detectMultiScale(smallImg1, faces1,1.1,2,CV_HAAR_SCALE_IMAGE,cv::Size(20,20)); printf("deteced faces:%d\n",(int)faces1.size()); for (int i=0; i<faces1.size(); i++) { //saturate_castについては http://opencv.jp/opencv-2svn/cpp/operations_on_arrays.html center1.x = cv::saturate_cast<int>((faces1[i].x + faces1[i].width*0.5)*scale);//scaleはここで戻していることに注意! center1.y = cv::saturate_cast<int>((faces1[i].y + faces1[i].height*0.5)*scale); radius1 = cv::saturate_cast<int>((faces1[i].width + faces1[i].height)*0.25*scale); } //loading resource file(for face) input=cv::imread(argv[1],1); if(input.empty()){ printf("ERROR:resource image not found!\n"); return 0; } //preprocessing cv::Mat gray, smallImg(cv::saturate_cast<int>(input.rows/scale),cv::saturate_cast<int>(input.cols/scale),CV_8UC1); cv::cvtColor(input, gray, CV_BGR2GRAY); cv::resize(gray, smallImg, smallImg.size(),0,0,cv::INTER_LINEAR); cv::equalizeHist(smallImg, smallImg);//ヒストグラムビンの合計値が 255 になるようヒストグラムを正規化 //find face size and generating mask cascade.detectMultiScale(smallImg, faces2,1.1,2,CV_HAAR_SCALE_IMAGE,cv::Size(20,20)); printf("deteced faces:%d\n",(int)faces2.size()); for (int i=0; i<1; i++) { //saturate_castについては http://opencv.jp/opencv-2svn/cpp/operations_on_arrays.html center2.x = cv::saturate_cast<int>((faces2[i].x + faces2[i].width*0.5)*scale);//scaleはここで戻していることに注意! center2.y = cv::saturate_cast<int>((faces2[i].y + faces2[i].height*0.5)*scale); radius2 = cv::saturate_cast<int>((faces2[i].width + faces2[i].height)*0.25*scale); p1.x=center2.x-radius;p1.y=center2.y-radius; p2.x=center2.x+radius;p2.y=center2.y+radius; cv::Rect roi_rect(center2.x-radius2,center2.y-radius2,radius2*2,radius2*2);//左上のx座標,y座標,width,depthというふうに格納していく mask_img.create(input.size(), CV_8UC3); mask_img=cv::Scalar(0,0,0);//真っ黒に not_masked=mask_img(roi_rect); not_masked=cv::Scalar(255,255,255);//真っ白に cvtColor(mask_img,mask_img_gray,CV_RGB2GRAY); input(roi_rect).copyTo(not_masked); } double ratio=(double)radius2/(double)radius1;// int difx=center1.x*ratio-center2.x; int dify=center1.y*ratio-center2.y; printf("%f%d%d\n",ratio,difx,dify); cv::Mat expanded_output(cv::saturate_cast<int>(dst_img.rows*ratio),cv::saturate_cast<int>(dst_img.cols*ratio),CV_8UC1); cv::resize(dst_img,expanded_output,expanded_output.size(),0,0,cv::INTER_LINEAR); //resizing source image & calc offset // //for debug(checking masks) // cv::namedWindow("input",1); // cv::namedWindow("result",1); // cv::namedWindow("masked",1); // cv::imshow("input", input); // cv::imshow("result", expanded_output); // cv::imshow("masked", mask_img); //ref:http://bicycle.life.coocan.jp/takamints/index.php/doc/opencv/doc/Mat_conversion// //http://d.hatena.ne.jp/kamekamekame877/20110621 IplImage buf1=input;//特殊なコピーコンストラクタが呼ばれてるかららしい IplImage buf2=mask_img_gray;//同じく IplImage buf3=expanded_output; im_src=&buf1; im_mask=&buf2; im_dst=&buf3; offset[0]=dify; offset[1]=difx; for(int i=0;i<3;i++){// i:channnels quasi_poisson_solver(im_src, im_dst, im_mask, i, offset); //poisson_solver(im_src, im_dst, im_mask, i, offset); } cvSaveImage(argv[3],im_dst); // cvReleaseImage(&im_src); // cvReleaseImage(&im_dst); // cvReleaseImage(&im_mask); return 0; }
int main(int argc, char *argv[]) { // 1. load classifier std::string cascadeeyeName = /*"Nariz.xml";*/"/usr/local/share/OpenCV/haarcascades/haarcascade_eye.xml";/*"frontalEyes35x16.xml";*//*"/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"; *///Haar-like std::string cascademouthName = "/usr/local/share/OpenCV/haarcascades/haarcascade_mcs_mouth.xml"; cv::CascadeClassifier cascadeeye, cascademouth; if(!cascadeeye.load(cascadeeyeName)){ printf("ERROR: cascadeeyeFile not found\n"); return -1; } if(!cascademouth.load(cascademouthName)){ printf("ERROR: cascademouthFile not found\n"); return -1; } cv::Mat doraemon = cv::imread(doraemon_file); cv::Mat doraemon_resized; // 2. initialize image char *input_file; // 1. prepare Mat objects for input-image and output-image cv::Mat input; if(argc == 2){ input_file = argv[1]; } else{ input_file = preset_file; } // 2. read an image from the specified file input = cv::imread(input_file,1); if(input.empty()){ fprintf(stderr, "cannot open %s\n", input_file); exit(0); } // 3. prepare window and trackbar cv::namedWindow("result", 1); //cv::namedWindow("mosaic", 1); cv::createTrackbar("size", "result", &size_of_mosaic, 30, 0); double scale = 4.0; cv::Mat gray, smallImg(cv::saturate_cast<int>(input.rows/scale), cv::saturate_cast<int>(input.cols/scale), CV_8UC1); //convert to gray scale cv::cvtColor( input, gray, CV_BGR2GRAY ); // 5. scale-down the image cv::resize(gray, smallImg, smallImg.size(), 0, 0, cv::INTER_LINEAR); cv::equalizeHist(smallImg, smallImg); // 6. detect face using Haar-classifier std::vector<cv::Rect> faces; ///multi-scale face searching // image, size, scale, num, flag, smallest rect cascadeeye.detectMultiScale(smallImg, faces, 1.1, 4,//この引数を大きくすると検出が早くなる CV_HAAR_SCALE_IMAGE);/*, cv::Size(30,30)*/ // 7. mosaic(pixelate) face-region //std::vector<cv::Rect>::const_iterator r = faces.begin(); int i; for(i=0;i<faces.size();++i){ cv::Point center; int radius; double radiusx, radiusy; center.x = cv::saturate_cast<int>((faces[i].x + faces[i].width*0.5)*scale); center.y = cv::saturate_cast<int>((faces[i].y + faces[i].height*0.5)*scale); radius = cv::saturate_cast<int>((faces[i].width + faces[i].height)*0.25*scale); //画像の縦横比で正規化 if(doraemon.size().width > doraemon.size().height) { radiusx = (double)radius; radiusy = (double)radius * doraemon.size().height / doraemon.size().width; } else { radiusy = (double)radius; radiusx = (double)radius * doraemon.size().width / doraemon.size().height; } //rakutencardman cv::Rect roi_rect(center.x-radiusx,center.y-radiusy, radiusx*2, radiusy*2); cv::Mat mosaic = input(roi_rect);//顔の部分を切り出している cv::resize(doraemon, doraemon_resized, mosaic.size()); mosaic = cv::Scalar(0,0,0);// doraemon_resized; cv::add(doraemon_resized, mosaic, mosaic); //cv::imshow("mosaic", mosaic); } printf("%d", (int)faces.size()); // 8. show mosaiced image to window cv::imshow("result", input ); while(1){ int c = cv::waitKey(); // 7. process according to input switch(c){ case 27://ESC case 'q': break; case 10://ENTER cv::imwrite("rakuten_cardman.jpg", input); break; } break; } return 0; }