Cómo detectar los bordes largos de la pared para preparar la máscara y recolorar
La idea principal es permitir al usuario recolorir a la pared específica basada en la selección del usuario. Actualmente he implementado esta característica usando cvFloodFill
(ayuda a preparar la imagen de la máscara) que puede ayudarme a cambiar el valor relativo de HSV
para la pared así que puedo conservar bordes. pero el problema con esta solución es que trabaja en color y todas las paredes se repintan en vez de la sola pared seleccionada por el usuario.
También he intentado la detección canny del borde pero apenas capaz de detectar el borde pero no capaz de convertirlo al área.
- Android: Umbral adaptativo
- ¿Cómo puedo escalar una imagen sin borrar?
- Conversión de mapa de bits: Creación de mapa de bits que excluye los lados transparentes del mapa de bits transparente
- Guardar / cargar el estado del documento de forma rápida y robusta para el editor de imágenes
- Rotación de la imagen YUV420 / NV21 en android
A continuación, encontrará el código que estoy utilizando actualmente para la función de repintado
-
Preparar la máscara
cvFloodFill(mask, new CvPoint(295, 75), new CvScalar(255, 255, 255,0), cvScalarAll(1), cvScalarAll(1), null, 4, null);
-
canal dividido
cvSplit(hsvImage, hChannel, sChannel, vChannel, null);
-
cambiar color
cvAddS(vChannel, new CvScalar(255*(0.76-0.40),0,0,0), vChannel, mask);
Cómo podemos detectar los bordes y el área correspondiente de la imagen.
Estoy buscando la solución que puede ser diferente de opencv
pero debería ser posible para el iPhone y Android
Editar
puedo alcanzar algo resultado como abajo imagen usando abajo pasos
cvCvtColor(image, gray, CV_BGR2GRAY); cvSmooth(gray,smooth,CV_GAUSSIAN,7,7,0,0); cvCanny(smooth, canny, 10, 250, 5);
hay dos problemas con esta salida no está seguro de cómo resolverlos 1. cerrar cerca de bordes 2. eliminar los bordes pequeños
- Escala y traducción de un mapa de bits en android
- Cómo combinar mapas de bits en android?
- Cómo crear piezas de rompecabezas sin usar máscara?
- Cómo cambiar el color de ciertos píxeles en el mapa de bits de Android
- Imágenes de captura automática de la cámara de recorte de Android
- TextureView.getBitmap () que muestra un rendimiento inconsistente
- ¿Cómo cambiar de forma programática el contraste de un mapa de bits en android?
- Evitar excepciones de memoria en la aplicación de filtros a imágenes (Android)
Creo que podría tener la solución para usted! Hay un archivo de ejemplo llamado watershed.cpp en OpenCV, sólo ejecútelo y obtendrá este resultado:
Puede hacer que su usuario dibuje en su pantalla para discriminar cada pared. Entonces, si desea algo más preciso, puede delinear las áreas (sin tocar otras líneas) de la siguiente manera:
¡Y TADA! :
Con un poco de trabajo puede hacer que sea fácil de usar (cancelar la última línea, conectar áreas etc …)
¡Espero que ayude!
Usted podría intentar algo como:
Mat imageOut = Mat::zeros(imageIn.rows, imageIn.cols, CV_8UC3); vector<vector<Point> > contours; vector<Vec4i> hierarchy; findContours( imageIn, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); for( int idx = 0; idx >= 0; idx = hierarchy[idx][0] ) { Scalar color( rand()&255, rand()&255, rand()&255 ); drawContours( imageOut, contours, idx, color, CV_FILLED, 8, hierarchy ); }
Debe dibujar las paredes en diversos colores. Si funciona, eso significa que en "jerarquía" cada pared se identifica como un contorno, entonces usted tendrá que averiguar que el usuario seleccionó en su pantalla táctil y hacer su proceso de ajuste de color.
Puede que tenga que cambiar los diferentes parámetros en el enlace "findContours". También tendrá que suavizar la imagen de entrada antes de la detección de contorno para evitar ser molestado con los detalles o texturas.
Espero que ayude, Thomas
Creo que puedes usar el algoritmo Canny Edge Detection
para encontrar la diferencia de bordes. Algunos enlaces
- Desbordamiento de pila
- Desbordamiento de pila
- OpenCV QA
- OpenCV
- Tutorial nativo
Espero que esto pueda ayudarte. Gracias.
Aquí está un código OpenCV4Android para encontrar el contorno más grande en una image
llamada Mat
, que asumiremos está en el espacio de color RGBA. Para encontrar contornos, primero es necesario limitar o binarizar la imagen (convertir a blanco y negro). El uso de un Gaussian Blur en la imagen antes del umbral reduce el número de pequeños contornos que se producen. Los parámetros de tamaño para el desenfoque y el umbral deben ser números impares; usted puede jugar alrededor para encontrar qué valor da los mejores resultados (aquí, he utilizado 7 para ambos).
List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat BW = new Mat(); Mat hierarchy = new Mat(); MatOfPoint largestContour; Imgproc.cvtColor(image, image, Imgproc.COLOR_RGBA2GRAY); // convert to grayscale Imgproc.GaussianBlur(image, BW, new Size(7,7), 0); Imgproc.adaptiveThreshold(BW, BW, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 7, 2.0); Imgproc.findContours(BW, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); double maxArea = 0; for (MatOfPoint contour : contours) { double area = Imgproc.contourArea(contour); if (area > maxArea) { maxArea = area; largestContour = contour; } }
hay dos problemas con esta salida no está seguro de cómo resolverlos 1. cerrar cerca de bordes 2. eliminar los bordes pequeños
-
Puede utilizar operaciones morfológicas para cerrar los bordes. Busque los operadores de dilatación y cierre.
-
Puede quitar los bordes pequeños haciendo etiquetas. Cuente el número de píxeles en cada región (píxeles blancos conectados). Elimine cualquier región con un número de píxeles inferior a algún umbral. No utilizo opencv, pero la mayoría de las bibliotecas tienen una función de etiquetado que creará una imagen en la que cada conjunto de píxeles conmovedores de un solo color recibirá un color único en la imagen de salida.
- El selector de dispositivos Android muestra la X roja en la columna de destino
- Aceleración del ciclo de vida de las aplicaciones de Android