La morfología matemática permite extraer estructuras específicas de una imagen mediante operacioens de dilatación y erosión con elementos estructurantes personalizados. En la dilatación estructurada, se asigna el valor máximo de la región cubierta por el elemento estructurante. En la erosión estructurada, se asigna el valor mínimo de dicha región.
1. Extracción de líneas horizontales
Se utiliza un elemento estructurante lineal horizontal para aislar las trazas horizontales de una imagen binaria.
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("L:/opencv_picture/14.png");
if (src.empty()) {
printf("Could not load image...\n");
return -1;
}
namedWindow("Input", WINDOW_AUTOSIZE);
imshow("Input", src);
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("Gray", gray);
Mat binary;
// Invertir la imagen para que las líneas sean blancas sobre fondo negro
adaptiveThreshold(~gray, binary, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
imshow("Binary", binary);
// Elemento horizontal: ancho = columnas/16, alto = 1
Mat hKernel = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1));
Mat temp;
erode(binary, temp, hKernel);
dilate(temp, dst, hKernel); // Apertura morfológica
bitwise_not(dst, dst); // Invertir para visualización
imshow("Horizontal lines", dst);
waitKey(0);
return 0;
}
2. Extracción de líneas verticales
Se cambia el elemento estructurannte a una forma vertical (ancho = 1, alto = filas/16).
// ... (mismo preámbulo que antes) ...
// Elemento vertical
Mat vKernel = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16));
Mat temp;
erode(binary, temp, vKernel);
dilate(temp, dst, vKernel);
bitwise_not(dst, dst);
imshow("Vertical lines", dst);
// ...
3. Extracción de rectángulos
Para extraer regiones rectangulares pequeñas se emplea un kernel cuadrado de 3×3.
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char** argv) {
Mat src, dst;
src = imread("L:/opencv_picture/15.bmp");
if (src.empty()) {
printf("Could not load image...\n");
return -1;
}
namedWindow("Input", WINDOW_AUTOSIZE);
imshow("Input", src);
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);
imshow("Gray", gray);
Mat binary;
adaptiveThreshold(~gray, binary, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);
imshow("Binary", binary);
// Kernel cuadrado 3x3 para rectángulos
Mat rectKernel = getStructuringElement(MORPH_RECT, Size(3, 3));
Mat temp;
erode(binary, temp, rectKernel);
dilate(temp, dst, rectKernel);
bitwise_not(dst, dst);
imshow("Rectangles", dst);
waitKey(0);
return 0;
}