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;
      }
    }
  }
}
Example #4
0
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;
   
}
Example #5
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;
}
Example #6
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;
}