c++ - OpenCV2 skin segmentation with back projection -
i'm trying observe human skin in video feed webcam using projection. utilize 1 of opencv's haar cascade classifiers observe face, , utilize part of forehead generate histogram projection observe other areas of skin. below result have far. result below best i've had far , still has lot of noise. have whole face (and other skin areas detected) 1 big connected component can draw contour around area detected skin. have no thought how go on , grateful if help suggestions, code snippets, etc.
here's code:
#include <opencv2/objdetect/objdetect.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <stdio.h> using namespace std; using namespace cv; matnd gethistogram(mat image); int lowthreshold = 20; int highthreshold = 20; int channels[] = {0, 1}; // hue & saturation float h_range[] = {0, 179}; float s_range[] = {0, 255}; const float *ranges[] = {h_range, s_range}; mat capturedframe, flippedframe, grayscaleframe, hsvimage, hueimage, mask, backprojectedimage, grayforcontour; std::vector< std::vector<cv::point> > contours; int main(int argc, const char **argv){ cascadeclassifier classifier; classifier.load("haarcascade_frontalface_alt2.xml"); videocapture capturedevice; capturedevice.open(0); namedwindow("webcam feed"); while(true){ capturedevice >> capturedframe; flip(capturedframe, flippedframe, 1); // grayness scale face detection cvtcolor(flippedframe, grayscaleframe, cv_bgr2gray); equalizehist(grayscaleframe, grayscaleframe); // hsv image conversion cvtcolor(flippedframe, hsvimage, cv_bgr2hsv); // separate hue channel used histogram in projection hueimage.create(hsvimage.size(), hsvimage.depth()); int ch[] = {0,0}; mixchannels(&hsvimage, 1, &hueimage, 1, ch, 1); std::vector<rect> faces; // store face found //find faces , store them in vector array classifier.detectmultiscale(grayscaleframe, faces, 1.1, 3, cv_haar_find_biggest_object|cv_haar_scale_image, size(30, 30) ); if ( faces.size() > 0 ){ (int = 0; < faces.size(); i++){ // /* origin backprojection forehead part of interst */ float topleft_x = faces[i].x + faces[i].width/ 4; float topleft_y = faces[i].y + faces[i].height / 16; float bottomright_x = topleft_x + faces[i].width / 2; float bottomright_y = topleft_y + faces[i].height/6; point roipt1( topleft_x, topleft_y ); point roipt2( bottomright_x, bottomright_y ); mat faceroi = flippedframe(cv::rect( topleft_x , topleft_y, bottomright_x - topleft_x, bottomright_y - topleft_y )); // namedwindow("roi"); // imshow("roi", faceroi); //draw rectangle of part of interst rectangle(flippedframe, roipt1, roipt2, scalar(0, 0, 255), 1, 8, 0); //convert forehead roi hsv mat roihsv; cvtcolor(faceroi, roihsv, cv_bgr2hsv); // histogram of hsv of roi matnd roihist = gethistogram(roihsv); normalize(roihist, roihist, 0, 255, norm_minmax, -1, mat()); // calculate backprojection of hue image calcbackproject(&hsvimage, 1, channels, roihist, backprojectedimage, ranges, 1, true); /* ending new backprojection effort */ // threshold projected image mat final; /* apply gaussian filter before thresholding otsu */ mat blur; gaussianblur(backprojectedimage, blur, size(5, 5),0); threshold(blur, final, 0,255,thresh_binary+thresh_otsu); // opening // erode(final, final, morph_rect); // dilate(final, final, morph_rect); //show backprojected image // namedwindow("back projection"); // imshow("back projection", backprojectedimage); namedwindow("threshold image after projection"); imshow("threshold image after projection", final); //drawing rectangle around found face point facept1(faces[i].x + faces[i].width, faces[i].y + faces[i].height); point facept2( faces[i].x, faces[i].y ); rectangle(flippedframe, facept1, facept2, cvscalar(0, 255, 0), 1, 8, 0); } } imshow("webcam feed", flippedframe); if (waitkey(10) == 27){ break; } } homecoming 0;
}
// histogram of forehead roi using hue , saturation matnd gethistogram(mat image){ matnd hist; int h_bins = 30; int s_bins = 32; int histsize[] = {h_bins, s_bins}; cv::calchist(&image, 1, channels, mat(), hist, 2, histsize, ranges); homecoming hist; }
and here's result have now:
c++ opencv computer-vision
No comments:
Post a Comment