Opencv 3 mask over the face by detectMultiScale - face detection
This tutorial demonstrates how to use OpenCV and C++ to detect faces in an image and replace them with a mask. By following these easy steps, you can achieve results similar to those of many popular face-enhancing applications. The tutorial assumes that you already have a video reader implemented in OpenCV and focuses on applying face detection and overlaying a mask on the detected faces.
Pixel-by-pixel color value filtering
Let me explain how to add a transparent mask over the ROI in a video sequence.It is easy to overlay an image of an anonymous mask with a white background onto a selected area of a video. The mask is added pixel by pixel, with the condition that it is only applied to the background video if the color of the mask is black. While there are other methods for adding the image over the region of interest (ROI), this approach allows for filtering by pixel color value.
The condition has the following logic
IF imageMask.at(xx,yy)[0] < 10 Then copy. The black color has a value (0,0,0). The code compares just the value of the mask in one channel[0] on location xx, yy. If the value of a pixel on channel [0] is less than 10. Based on the source mask image which has just values (0,0,0) or (255,255,255) the condition is going to copy the black part. Otherwise, the white part is not copied to the source image which makes the part of the face transparent through the mask.
The detectMultiScale in Opencv 3
function takes several parameters that you can adjust to fine-tune face detection.:detectMultiScale(Input Image, Output detections, ScaleFactor, minNeighbors, flags, minSize, MaxSize.
scaleFactor
: This parameter specifies how much the image size is reduced at each scale. A value of1.05
means that the image is reduced by 5% at each scale. A smaller value will increase the chance of detecting faces but will also slow down the algorithm.minNeighbors
: This parameter specifies how many neighbors each candidate rectangle should have to be retained. A higher value will result in fewer detections but with higher quality.minSize
: This parameter specifies the minimum size of objects to be detected. Objects smaller than this size will be ignored.maxSize
: This parameter specifies the maximum size of objects to be detected. Objects larger than this size will be ignored.
How to replace the defective part with a Mask pixel-by-pixel
You can replace a single pixel by pixel by:
image1.at<cv::Vec3b>(y1, x1) = image2.at<cv::Vec3b>(y2, x2);
The second way is almost similar, but you will replace pixel by pixel in a concrete color channel.
// Load the two imagescv::Mat image1 = cv::imread("image1.jpg");cv::Mat image2 = cv::imread("image2.jpg");// Coordinates of the pixel to be replaced in image1int x1 = 10;int y1 = 20;// Coordinates of the pixel to be used from image2int x2 = 30;int y2 = 40;// You can do in for position x,y where number in [x]// y1,x1 are coordinates where tu copy content of pixel// of image2 from location x2,y2// represent the channel B,G,Rimage1.at(y1,x1)[0] = image2.at(x2,y2)[0];image1.at(y1,x1)[1] = image2.at(x2,y2)[1];image1.at(y1,x1)[2] = image2.at(x2,y2)[2];// Save the modified imagecv::imwrite("modified_image.jpg", image1);
Code Opencv Tutorial - Mask face detection
The pixel-by-pixel replacement of the detected rectangle by the mask is valid for Opencv 3 and 4. In general, I can recommend replacing CascadeClassifier with some neural network in the DNN module to detect faces.
//Normal face detection by haar cascade in opencv CascadeClassifier faceDetector; bool loaded1 = faceDetector.load("facehaarcascade.xml"); Mat original; img.copyTo(original); std::vector faces; cvtColor(img, img, CV_BGR2GRAY); equalizeHist(img, img); detectorBody.detectMultiScale(img, faces, 1.1, 2, 0 | 1, Size(40, 40), Size(400,400 ));
Mat Original; //Read the anonymous mask Mat imageMask = imread("MASK.png", 1);// Draw the mask over all rectanglesfor( size_t i = 0; i < faces.size(); i++ ) { int xx =0, yy =0; // Just iterate in face region pixel by pixel for(int x = faces[i].x; x < faces[i].x+faces[i].width; x++) { for (int y = faces[i].y; y < faces[i].y+faces[i].height; y++) { //This is core of the trick. // Copy Mask to Original image If the 0 chan // Proper condition is over all color channels // imageMask.at(xx,yy)[0] < 10 // imageMask.at(xx,yy)[1] < 10 // imageMask.at(xx,yy)[2] < 10 // Black Color(0,0,0) if (imageMask.at(xx,yy)[0] < 10) { // Copy to original image on (y,x) places the pixel of xx,yy mask Original.at(y,x)[0] = imageMask .at(xx,yy)[0]; Original.at(y,x)[1] = imageMask .at(xx,yy)[1]; Original.at(y,x)[2] = imageMask .at(xx,yy)[2]; } // Iterate in mask x xx =xx+1; } // iterate next row of imageMask xx = 0; yy =yy+1; } }]
so interesting! can i have full source code bro? :D
This is almost full source code! You only need capture video from video file or web camera. Put this image or image sequence into Mat Original; and apply the mask (Code is here). I am sorry this is more than enough. You only need to video input loop.
java codings with examples
I am sorry this is more than enough. You only need to video input loop.
โกลเด้นสล็อต
goldenslot
Great work! I want to do something like placing image on the eyes. How can I get it done? Any ideas? I'd really love to know. Thank you! :D
Videos and articles are good and useful.
goldenslot
This comment has been removed by the author.
It is a subject that is novel and very interesting to follow.
viva9988 holiday