Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aligning the face #19

Open
MyraBaba opened this issue Dec 26, 2023 · 16 comments
Open

aligning the face #19

MyraBaba opened this issue Dec 26, 2023 · 16 comments

Comments

@MyraBaba
Copy link

Hi, @Qengineering

what I noticed that you are aligning the face in TWrap:


 cv::warpPerspective(SmallFrame, aligned, m, cv::Size(96, 112), cv::INTER_LINEAR);
  resize(aligned, aligned, cv::Size(112, 112), 0, 0, cv::INTER_LINEAR);

I saw from ncnn repo:
[
cv::warpAffine(img_src.clone(), *face_aligned, transfer_mat, cv::Size(112, 112), 1, 0, 0);)

is this make a huge diference ? you are usingb (cv::Size(96, 112)) after that resing , below one ise directly 112,112

would you mind to look at it ?

@Qengineering
Copy link
Owner

The difference is subtle.
In warpAffine() is *face_aligned a [2x3] matrix, as where in warpPerspective, aligned a [3x3] matirx is. For more info see the OpenCV docs.

@MyraBaba
Copy link
Author

MyraBaba commented Dec 26, 2023 via email

@Qengineering
Copy link
Owner

If not implemented, try to get a check on the rotation before acceptance.

@MyraBaba
Copy link
Author

@Qengineering

here after aligment :
Screenshot from 2023-12-26 14-08-05

@Qengineering
Copy link
Owner

I see.
The key to solve this issue is the aligned [3x3] matirx.
The factors determine how the image is transformed.
Investigate the factors. It is relatively simple to detect a large rotation.
The OpenCV docs give you more informations.

@MyraBaba
Copy link
Author

MyraBaba commented Dec 27, 2023 via email

@MyraBaba
Copy link
Author

@Qengineering
would you mind to give me the example cpp part ? really confused on c++

@Qengineering
Copy link
Owner

Tip:

You: Can you calculate in a C++ program using the OpenCV function cv::warpPerspective(SmallFrame, aligned, m, cv::Size(96, 112), cv::INTER_LINEAR); a rotation angle of the image in degrees?

Answer ChatGTP:
Certainly! To calculate the rotation angle from a perspective transformation matrix, you can use the following C++ code. This assumes that the transformation matrix m is a 3x3 matrix obtained from the cv::getPerspectiveTransform function or some other method.

#include <opencv2/opencv.hpp>

int main() {
    // Read the original image
    cv::Mat SmallFrame = cv::imread("path/to/your/image.jpg");

    // Define the transformation matrix (you should have this matrix from somewhere)
    cv::Mat m = (cv::Mat_<double>(3, 3) << 1, 0, 0, 0, 1, 0, 0, 0, 1);

    // Perform the perspective transformation
    cv::Mat aligned;
    cv::warpPerspective(SmallFrame, aligned, m, cv::Size(96, 112), cv::INTER_LINEAR);

    // Calculate rotation angle
    double angle = atan2(m.at<double>(1, 0), m.at<double>(0, 0)) * 180.0 / CV_PI;

    // Print the rotation angle
    std::cout << "Rotation angle: " << angle << " degrees." << std::endl;

    return 0;
}

In this code, atan2 is used to calculate the angle from the transformation matrix elements. The rotation angle is stored in the variable angle and then printed. Note that this assumes the transformation matrix represents only a rotation and not a more complex transformation. If your transformation matrix includes other elements, you may need a more sophisticated approach to extract rotation information.

@MyraBaba
Copy link
Author

MyraBaba commented Dec 27, 2023 via email

@Qengineering
Copy link
Owner

Believe me, I have the same feelings towards AI as you. Hesitated a lot.
However, a free clever 'student' at my side, finding some answers, which I undoubtedly had found also, but a few times faster, enlighten my rather heavy workload.
I'm not impressed by AI. It's boring when you look at close.

@MyraBaba
Copy link
Author

@Qengineering

Quick note:

double angle = atan2(m.at<double>(1, 0), m.at<double>(0, 0)) * 180.0 / CV_PI;

is not producing right result unless you change to double to float.

double angle = atan2(m.at<float>(1, 0), m.at<float>(0, 0)) * 180.0 / CV_PI;

by the way I try to use yolov5 cpp face detection (the version which has not accuracy percentage return) .
what would be the superior over scrfd and yolov5 face detection ? do you have any experience for yolov7/8 cpp face detection ?
Best

@Qengineering
Copy link
Owner

I haven't any experience of YoloV7 or V8 with face detection.
Please note that not only the faces need to be detected, but also the position of the eyes, nose and mouth.
I'm not sure if the face detectors based on Yolo feature this.

@MyraBaba
Copy link
Author

MyraBaba commented Dec 28, 2023 via email

@Qengineering
Copy link
Owner

OK.. You could try it. However, YoloV5 might be a lot slower. (??)

@MyraBaba
Copy link
Author

MyraBaba commented Dec 28, 2023 via email

@Qengineering
Copy link
Owner

As shown in the README, there are two options implemented. MTCNN or Retinaface. The later somewhat slower.
Look for more details in their academic papers. Both work well and are fast.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants