opencv encontrar casco cóncavo
image-processing interpolation (1)
Eche un vistazo a las transformaciones morfológicas. Comenzaría con una operación de dilatación usando un kernel grande, digamos el MORPH_ELLIPSE con un tamaño (15,15). Luego, diluya los blobs de nuevo usando la operación de erosión con el mismo tamaño de kernel. Eche un vistazo a los documentos aquí . Tenga en cuenta que OpenCV también ofrece operaciones morfológicas encadenadas o secuenciadas. Mira aquí . Verás que mi sugerencia es una operación de "cierre".
Actualización: Experimenté con una simple dilatación y contorneado para obtener los resultados que se muestran en la imagen. Los resultados parecen satisfacer los requisitos generales del problema.
Del mismo modo, no se especifica qué significa "en tiempo real" para la aplicación, pero este conjunto de operaciones se puede ejecutar rápidamente y se puede aplicar fácilmente a una aplicación de 30 fps.
Fragmento de código a continuación:
// Convert image to grayscale
cvtColor(src, gray, CV_BGR2GRAY);
threshold(gray, gray, 128.0, 128.0, THRESH_BINARY);
// Dilate to fill holes
dilate(gray, dest, getStructuringElement(MORPH_ELLIPSE, Size(13,13)));
// Find contours
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(dest, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0));
// Prune contours
float maxArea = 0.0f;
for (size_t i = 0; i< contours.size(); i++)
{
if (contourArea(contours[i]) >= maxArea)
{
maxArea = contourArea(contours[i]);
}
}
float minArea = 0.20f * maxArea;
vector<vector<Point> > prunedContours;
for (size_t i = 0; i< contours.size(); i++)
{
if (contourArea(contours[i]) >= minArea)
{
prunedContours.push_back(contours[i]);
}
}
// Smooth the contours
vector<vector<Point> > smoothedContours;
smoothedContours.resize(prunedContours.size());
for (size_t i=0;i<prunedContours.size();i++)
{
vector<float> x;
vector<float> y;
const size_t n = prunedContours[i].size();
for (size_t j=0;j<n;j++)
{
x.push_back(prunedContours[i][j].x);
y.push_back(prunedContours[i][j].y);
}
Mat G;
transpose(getGaussianKernel(11,4.0,CV_32FC1),G);
vector<float> xSmooth;
vector<float> ySmooth;
filter2D(x,xSmooth, CV_32FC1, G);
filter2D(y,ySmooth, CV_32FC1, G);
for (size_t j=0;j<n;j++)
{
smoothedContours[i].push_back(Point2f(xSmooth[j],ySmooth[j]));
}
}
Tengo un conjunto de puntos discretos que se muestran en una imagen, como el siguiente
Quiero reconstruir o subir el muestreo (no estoy seguro de cuál es la forma correcta de describirlo) de la imagen, para que la imagen resultante sea como la siguiente . No es necesario que sea exactamente igual a la imagen de ejemplo, pero la idea principal es llenar el original.
Tengo una idea inicial sobre cómo hacerlo. Pero no sé cómo hacerlo después del primer paso. Mi idea es primero separar la imagen usando kmeans y descubrir los diferentes objetos. Y lo he logrado con éxito. Las imágenes resultantes después de kmeans son: .
Después de kmeans, quiero usar el contorno de encontrar o algo así como cóncavo para obtener el contorno de estas formas y llenar la forma usando funciones como agujeros de relleno. Sin embargo, encontré que "encontrar contorno" no funciona, considerará cada píxel individual como un contorno.
La otra manera que estoy pensando es usar interpolación. Pero no estoy seguro de si es posible con puntos tan escasos. ¿Alguien tiene alguna idea sobre cómo hacer esto? No estoy seguro de si estoy en el camino correcto y estoy abierto a cualquier solución.
¡Muchas gracias!