お世話になってます。
現在大学3年生で最近プログラミングの勉強を始めた者です。
顔と鼻検出をしてそれを描画するプログラムを書いているところですが、
顔の中にない鼻は描画しないようにしています。
困っていることは、一人の顔に対して複数の鼻が検出された時です。
顔の中に鼻が2つ以上検出された時、顔中心にある方を描画するような
プログラムを書きたいのですが、具体的にどうかき足せば良いかわかりません。
教えていただきたいですm(_ _)m
開発環境
xcode opencv3 c++
C++
1int main(int argc, const char * argv[]) { 2 3 cv::Mat black_image = cv::Mat::zeros(cv::Size(640, 480), CV_8UC3); 4//分類器読み込み 5 std::string cascadeName = "/usr/local/Cellar/opencv3/3.2.0/share/OpenCV/haarcascades/haarcascade_frontalface_default.xml"; 6 std::string cascadeName1 = "/usr/local/Cellar/opencv3/3.2.0/share/OpenCV/haarcascades/haarcascade_mcs_nose.xml"; 7 cv::CascadeClassifier cascade; 8 cv::CascadeClassifier cascade1; 9 if (!cascade.load(cascadeName)) return -1; 10 if (!cascade1.load(cascadeName1))return -1; 11 std::vector<cv::Rect> faces; 12 std::vector<cv::Rect> nose; 13 14 double ppl[10]; 15 int facex[10]; 16 int facey[10]; 17 int facer[10]; 18 19 cv::Mat frame; 20 cv::Mat input_image; 21 cv::Mat output_image; 22 frame = imread("/usr/local/kenshi/test1 (3).jpg",IMREAD_COLOR ); 23 //cv::resize(frame, frame, cv::Size(), 1000.0/frame.cols ,1000.0/frame.cols); 24 cvtColor(frame, input_image, CV_BGR2GRAY); 25 cv::equalizeHist(input_image, input_image); 26 output_image = frame; 27 28 flip(output_image, output_image, 1); 29 flip(input_image, input_image, 1); 30 31 cv::namedWindow("meter", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO); 32 cv::namedWindow("window", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO); 33 34 cascade.detectMultiScale(input_image, faces, 35 1.1, 3, 36 CV_HAAR_SCALE_IMAGE 37 , 38 cv::Size(600, 600)); 39 40 cascade1.detectMultiScale(input_image, nose, 41 1.1, 3, 42 CV_HAAR_SCALE_IMAGE 43 , 44 cv::Size(50, 50)); 45 46 std::vector<cv::Rect>::const_iterator r = faces.begin(); 47 std::vector<cv::Rect>::const_iterator r1 = nose.begin(); 48 49 int radius; 50 int radius1; 51 52 cv::Point center; 53 int b =0; 54 for (; r != faces.end(); ++r) { 55 56 center.x = cv::saturate_cast<int>((r->x + r->width*0.5)); 57 center.y = cv::saturate_cast<int>((r->y + r->height*0.5)); 58 radius = cv::saturate_cast<int>((r->width + r->height)*0.25); 59 cv::circle(output_image, center, radius, cv::Scalar(80, 80, 255), 3, 8, 0); 60 61 facex[b] = center.x; 62 facey[b] = center.y; 63 facer[b] = radius; 64 b++; 65 66 } 67 68 //色 69 int color[10]; 70 int t = 10000000; 71 for(int i = 0; i<10; i++) color[i] = 100 * i; 72 73 cv::Point center1; 74 int k = 0; 75 76 for (; r1 != nose.end(); ++r1) { 77 center1.x = cv::saturate_cast<int>((r1->x + r1->width*0.5)); 78 center1.y = cv::saturate_cast<int>((r1->y + r1->height*0.5)); 79 radius1 = cv::saturate_cast<int>((r1->width + r1->height)*0.25); 80 81 for(int i = 0; i < b; i++){ 82 int u = (facex[i]-center1.x)*(facex[i]-center1.x)+(facey[i]-center1.y)*(facey[i]-center1.y); 83 int m = facer[i] * facer[i]; 84 85 if(u < m){ 86 87 88 cv::circle(output_image, center1, radius1, cv::Scalar(color[i], 0, color[i]), 3, 8, 0); 89 //顔、鼻、角度セットで出力して角度を配列に格納 90 91 printf("nose(%d,%d)\n", center1.x, center1.y); 92 printf("face(%d,%d)\n", facex[i], facey[i]); 93 printf("radius%d\n", facer[i]); 94 double rad = angle(int(facex[i]), int(center1.x)); 95 96 ppl[k] = rad; 97 printf("k=%d,angle:%f\n", k,rad ); 98 printf("u=%d,m=%d\n",u,m); 99 100 k++; 101 break; 102 103 } 104 } 105 } 106 107 cv::Point circle; 108 cv::Point circle1; 109 for(int i = 0; i < b; i++){ 110 circle.x = 60 + 120 * (i); 111 circle.y = 60 ; 112 cv::circle(black_image, circle, 50, cv::Scalar(80, 80, 255), -1, 4, 0); 113 114 circle1.x = circle.x - 50 * cos(M_PI / 2 - ppl[i]); 115 circle1.y = circle.y - 50 * sin(M_PI / 2 - ppl[i]); 116 117 cv::line(black_image, circle, circle1, cv::Scalar(color[i], 0, color[i]), 3, 1, 0); 118 119 } 120 121 cv::resize(output_image, output_image, cv::Size(), 1000.0/output_image.cols ,1000.0/output_image.cols); 122 123 imshow("meter", black_image); 124 imshow("window", output_image); 125 126 cv::waitKey(0); 127 return 0; 128}
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/01/18 02:23