I think the other answer is way to complicated for this problem.
Basically you will need to do the following steps
- Convert your region of interest (detection) to HSV color space by using the cvtColor function with the CV_BGR@HSV parameter.
- Now define the max and min value of H S and V channel.
- Use these values to get a good segmentation of the original values
This code snippet should do about what you need. It contains much more functionality, but it shouldn't be hard to filter out the needed parts, which I have no time for now.
// workshop_face_detect.cpp : Performing LBP CUDA face detection on live video stream
// Make it possible to segment out skin color
#include <opencv/cv.h>
#include <opencv/cvaux.h>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/gpu/gpu.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
gpu::CascadeClassifier_GPU face_cascade;
// Basic function to calculate gradient magnitude and angle matrix based on input
vector<Mat> calculate_gradient(Mat input){
Mat img_smooth;
GaussianBlur( input, img_smooth, Size(11,11), 5);
Mat grad_x = Mat(img_smooth.rows, img_smooth.cols, CV_64F);
Mat grad_y = Mat(img_smooth.rows, img_smooth.cols, CV_64F);
Sobel( img_smooth, grad_x, CV_64F, 1, 0, 3, 1, 0, BORDER_DEFAULT );
Sobel( img_smooth, grad_y, CV_64F, 0, 1, 3, 1, 0, BORDER_DEFAULT );
Mat magnitude = Mat(img_smooth.rows, img_smooth.cols, CV_64F);
sqrt(grad_x.mul(grad_x) + grad_y.mul(grad_y), magnitude);
Mat orientations = Mat(img_smooth.rows, img_smooth.cols, CV_64F);
for(int i = 0; i < img_smooth.rows; i++){
for(int j = 0; j < img_smooth.cols; j++){
orientations.at<double>(i,j) = fastAtan2(grad_x.at<double>(i,j), grad_y.at<double>(i,j));
}
}
vector<Mat> output;
output.push_back(magnitude);
output.push_back(orientations);
return output;
}
// Based on radial coördinates (angle and magnitude) calculate corresponding carthesian coördinates (x,y)
// Specific for OpenCV coördinate system
vector<Point> radial_to_carthesian(Point start, double angle, double magnitude){
const double PI = 3.141592;
// Since sin and cos functions already return values between [-1,1] we do not need to calculate signs for quadrants
// However, this corner is still given a standard
double angle_rad = angle * PI / 180;
double x_temp = cos(angle_rad) * magnitude;
double y_temp = sin(angle_rad) * magnitude;
double x_2 = start.x + x_temp;
double y_2 = start.y + y_temp;
// Create points
vector<Point> result;
result.push_back(start);
result.push_back(Point(x_2, y_2));
return result;
}
Mat visualize_gradients(vector<Mat> gradients, Mat input, int step, int magnitude){
Mat result = Mat(input.rows, input.cols, input.type());
input.copyTo(result);
for(int i = 3; i < input.rows; i = i + step){
for(int j = 3; j < input.cols; j = j + step){
// the points (i,j) now loop through the image with points to draw
// check in which quadrant the angle lies and then compute the correct x and y length
// Since data is now provided as [0-1] ranges, we need to multiply with 360 to get the actual angle
double angle = gradients[1].at<double>(i,j) * 360;
vector<Point> line_positions = radial_to_carthesian(Point(j,i), angle, magnitude);
line(result ...
(more)