You can use this program. Give image path as first argument. Select a rectangle and press g key values are printed in console.
#include "opencv2/opencv.hpp"
#include <iostream>
#include <map>
using namespace cv;
using namespace std;
const String keys =
"{Aide h usage ? help | | Afficher ce message }"
"{@arg1 | | chemin complet de l'image couleur (3 canaux)}"
;
struct ParamColorSpace {
int rctEnCours;
Rect r;
Mat img;
map<int, String> spaceName;
map<int, Mat> colorSpace;
String nomFenetre;
};
void DefRectangle(int event, int x, int y, int flags, void *userData)
{
ParamColorSpace *pgc = (ParamColorSpace*)userData;
if (flags == EVENT_FLAG_LBUTTON)
{
if (pgc->rctEnCours == 0)
{
pgc->r.x = x;
pgc->r.y = y;
pgc->r.width = 0;
pgc->r.height = 0;
pgc->rctEnCours = 1;
}
else if (pgc->rctEnCours == 1)
{
Point tl = pgc->r.tl(), br = pgc->r.br();
if (x != pgc->r.x)
{
if (x < pgc->r.x)
{
pgc->r.x = x;
pgc->r.width = br.x - x - 1;
}
else
pgc->r.width = x - tl.x - 1;
}
if (y != pgc->r.y)
{
if (y < pgc->r.y)
{
pgc->r.y = y;
pgc->r.height = br.y - y - 1;
}
else
pgc->r.height = y - tl.y - 1;
}
if (pgc->r.br().x > pgc->img.size().width)
{
pgc->r.width = pgc->img.size().width - pgc->r.x;
}
if (pgc->r.br().y > pgc->img.size().height)
{
pgc->r.height = pgc->img.size().height - pgc->r.y;
}
}
}
else if (event == EVENT_LBUTTONUP && pgc->rctEnCours == 1)
{
Point tl = pgc->r.tl(), br = pgc->r.br();
pgc->rctEnCours = 0;
}
Mat r = pgc->img.clone();
rectangle(r, pgc->r, Scalar(0, 255, 0), 2);
imshow(pgc->nomFenetre, r);
waitKey(10);
}
int main(int argc, char* argv[])
{
CommandLineParser parser(argc, argv, keys);
if (parser.has("help"))
{
parser.printMessage();
return 0;
}
String nomFic = parser.get<String>(0);
//nomFic = "c:/lib/opencv/samples/data/baboon.jpg";
if (nomFic.length() == 0)
{
parser.printMessage();
return 0;
}
ParamColorSpace pgc;
pgc.rctEnCours = 0;
pgc.img = imread(nomFic, IMREAD_COLOR);
pgc.nomFenetre = "My Image";
pgc.spaceName.insert(make_pair(CV_BGR2HSV, String("HSV")));
pgc.spaceName.insert(make_pair(CV_BGR2YUV, String("YUV")));
imshow(pgc.nomFenetre, pgc.img);
setMouseCallback(pgc.nomFenetre, DefRectangle, &pgc);
Mat mask, background, foreground;
Mat mk, bk, fk;
bool initGrabCut = false;
mask = Mat(pgc.img.size(), CV_8UC1, Scalar::all(cv::GC_PR_BGD));
int code = 0;
do
{
code = waitKey(30) & 0xFF;
if (code=='g')
{
mask = Mat(pgc.img.size(), CV_8UC1, Scalar::all(0));
mask(pgc.r) = 255;
map<int, String>::iterator ite = pgc.spaceName.begin();
for (; ite!=pgc.spaceName.end(); ite++)
{
if (pgc.colorSpace.find(ite->first) == pgc.colorSpace.end())
{
Mat s;
cvtColor(pgc.img, s, ite->first);
pgc.colorSpace.insert(make_pair(ite->first, s));
}
if (pgc.colorSpace.find(ite->first) == pgc.colorSpace.end())
return -1;
Mat mean, std;
Mat c = pgc.colorSpace.find(ite->first)->second;
meanStdDev(c, mean, std, mask);
cout << "Color Space :" << ite->second << "\n";
cout << "Mean : " << mean.t() << "\n";
cout << "Std : " << std.t() << "\n";
}
}
}
while (code != 27);
}
Create some sliders?
I did so. But not success with all 4 photos
My experience with HSV is that it is not as great a solution as one would like. The real world has noisy cameras, shadows, multiple light sources, reflections, and specularities, it will be nearly impossible to find values that select only the glove for all 4 images. You will likely need to do some aggregation/thresholding/filtering.