El algoritmo es el siguiente:
- convertir una imagen de entrada a YCbCr color space lo cual es bueno para detectar azul (y también rojo): Convertir alguna imagen a otro espacio de color uso cvtColor.
- Extraiga el canal azul de él: Utilice la función
extractChannel
para extraer el canal necesario.
- Detecta regiones con mayor valor [0-255] de color azul. Usé la función minMaxIdx y luego multipliqué el máximo en 0.8 (este es el umbral). Puede usar métodos más complejos como el análisis de histogramas.
- Haga una máscara de color azul: Para esto utilicé la función threshold calculada en el umbral del paso 3 (como parámetro).
- Encuentra todos los contornos azules en la máscara. En OpenCV es fácil: solo use findContours.
- Y, finalmente, detectar el contorno con el cuadrado más grande y encontrar sus coordenadas (centro). Para calcular el contorno con el cuadrado más grande puede usar la función contourArea.
También en lugar de pasos 1-4 que puede convertir la imagen a HSV y el uso de inRange detectar el color azul.
Aquí es mi C++ impementation:
Mat inMat = imread("input.jpg"), blueMat, threshMat;
cvtColor(inMat, blueMat, CV_BGR2YCrCb);//convert to YCrCb color space
extractChannel(blueMat, blueMat, 2);//get blue channel
//find max value of blue color
//or you can use histograms
//or more complex mathod
double blueMax;
minMaxIdx(blueMat, 0, &blueMax);
blueMax *= 0.8;
//make binary mask
threshold(blueMat, threshMat, blueMax, 255, THRESH_BINARY);
//finding all blue contours:
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(blueMat, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
double maxSquare = 0;
vector<Point> maxContour;
//finding contours with biggest square:
for (size_t i=0; i<contours.size(); i++)
{
double square = contourArea(contours[i]);
if (square > maxSquare)
{
maxContour = contours[i];
maxSquare = square;
}
}
//output results:
Point center = centerPolygon(maxContour);
cout << "square = " << maxSquare << endl;
cout << "position: x: " << center.x << ", y: " << center.y << endl;
Aquí es centerPolygon
función:
Point centerPolygon(const vector<Point>& points)
{
int x=0, y=0;
for (size_t i=0; i<points.size(); i++)
{
x += points[i].x;
y += points[i].y;
}
return Point(x/points.size(), y/points.size());
}
La salida del programa es el siguiente:
square = 263525
position: x: 318, y: 208
usted puede convertir el código de JavaCV - Ver this tutorial.
un nuevo usuario solo puede agregar 2 enlaces:/aquí está la máscara, creo que para compararla con la segunda imagen [ver imagen 3] (http://img441.imageshack.us/img441/8231/maskt.jpg) –
¿Quieres detectar el color azul o el color con el cuadrado más grande? – ArtemStorozhuk
quiero el tamaño y la posición del cuadrado/área más grande que tienen el color azul –