| 897 | } |
| 898 | |
| 899 | RoiInfo calcuateLipsRegionInfo(const std::vector<Point2f>& points, int radius/* = 0*/, const Scalar& color/*= Scalar(255, 255, 255, 255)*/) |
| 900 | { |
| 901 | // Due to the speed factor, mouth haven't been taken skew into consideration. |
| 902 | float left = points[63].x, right = points[69].x; |
| 903 | float top = std::min(points[65].y, points[67].y), bottom = points[78].y; |
| 904 | |
| 905 | Rect2f rect; |
| 906 | left -= radius; right += radius; |
| 907 | top -= radius; bottom += radius; |
| 908 | |
| 909 | Point2f origion(left, top); |
| 910 | Point2f pivot(points[74].x + radius, points[74].y + radius); |
| 911 | Rect region(cvRound(left), cvRound(top), cvRound(right - left), cvRound(bottom - top)); |
| 912 | Size size = region.size(); |
| 913 | Mat mask(size, CV_8UC1, Scalar::all(0)); // Bitmap.Config.A8 transparent |
| 914 | #if 0 |
| 915 | const int index_lips[] = |
| 916 | { |
| 917 | 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, // upper |
| 918 | 63, 73, 74, 75, 69, 76, 77, 78, 79, 80, // lower |
| 919 | }; |
| 920 | |
| 921 | std::vector<Point> contour; |
| 922 | contour.reserve(NELEM(index_lips)); |
| 923 | for(size_t j = 0; j < NELEM(index_lips); ++j) |
| 924 | { |
| 925 | const int& i = index_lips[j]; |
| 926 | float x = points[i].x - left; // make it relative |
| 927 | float y = points[i].y - top; |
| 928 | contour.push_back(Point(cvRound(x), cvRound(y))); |
| 929 | } |
| 930 | |
| 931 | const Point* polygons[2] = { contour.data(), contour.data() + contour.size()/2 }; |
| 932 | const int num_points[] = { static_cast<int>(contour.size()/2), static_cast<int>(contour.size()/2) }; |
| 933 | cv::fillPoly(mask, polygons, num_points, 2, color); // white |
| 934 | #else |
| 935 | std::vector<Point> contour; |
| 936 | auto push = [&contour, &left, &top](const Point2f& point) { contour.push_back(Point(cvRound(point.x - left), cvRound(point.y - top))); }; |
| 937 | // upper lip |
| 938 | for(int i = 63; i <= 72; ++i) |
| 939 | push(points[i]); |
| 940 | |
| 941 | // lower lip |
| 942 | push(points[63]); |
| 943 | push(points[73]); |
| 944 | push(catmullRomSpline(1.0f/3, points[63], points[73], points[74], points[75])); |
| 945 | push(catmullRomSpline(2.0f/3, points[63], points[73], points[74], points[75])); |
| 946 | push(points[74]); |
| 947 | |
| 948 | push(catmullRomSpline(1.0f/3, points[73], points[74], points[75], points[69])); |
| 949 | push(catmullRomSpline(2.0f/3, points[73], points[74], points[75], points[69])); |
| 950 | push(points[75]); |
| 951 | |
| 952 | push(points[69]); |
| 953 | push(points[76]); |
| 954 | |
| 955 | for(int i = 76; i <= 79; ++i) |
| 956 | { |
no test coverage detected