c++ - ¿Aplicar máscara a la imagen en OpenCV?
image-processing mask (5)
Tengo una máscara binaria que quiero que se aplique permanentemente a una imagen en color. ¿Cómo hago esto? La máscara binaria debe ser preferiblemente permanente, ya que no quiero volver a aplicar la máscara a la imagen cada vez que llamo a una función.
Se apreciarán ejemplos de código básico. Si usa el código, explíquelo en lugar de simplemente publicarlo.
Gracias
Aquí hay algo de código para aplicar una máscara binaria en una secuencia de fotogramas de video adquirida desde una cámara web. comente y descomente la línea "bitwise_not (Mon_mask, Mon_mask);" y vea el efecto.
mejores, Ahmed.
#include "cv.h" // include it to used Main OpenCV functions.
#include "highgui.h" //include it to use GUI functions.
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
int c;
int radius=100;
CvPoint2D32f center;
//IplImage* color_img;
Mat image, image0,image1;
IplImage *tmp;
CvCapture* cv_cap = cvCaptureFromCAM(0);
while(1) {
tmp = cvQueryFrame(cv_cap); // get frame
// IplImage to Mat
Mat imgMat(tmp);
image =tmp;
center.x = tmp->width/2;
center.y = tmp->height/2;
Mat Mon_mask(image.size(), CV_8UC1, Scalar(0,0,0));
circle(Mon_mask, center, radius, Scalar(255,255,255), -1, 8, 0 ); //-1 means filled
bitwise_not(Mon_mask,Mon_mask);// commenté ou pas = RP ou DMLA
if(tmp != 0)
imshow("Glaucom", image); // show frame
c = cvWaitKey(10); // wait 10 ms or for key stroke
if(c == 27)
break; // if ESC, break and quit
}
/* clean up */
cvReleaseCapture( &cv_cap );
cvDestroyWindow("Glaucom");
}
Bueno, esta pregunta aparece en la parte superior de los resultados de búsqueda, así que creo que necesitamos un ejemplo de código aquí. Aquí está el código de Python:
import cv2
def apply_mask(frame, mask):
"""Apply binary mask to frame, return masked image.
"""
return cv2.bitwise_and(frame, frame, mask=mask)
La máscara y el marco deben ser del mismo tamaño, por lo que los píxeles permanecen como están donde la máscara es 1
y se establecen en cero donde la máscara es 0
.
Y para C++
es un poco diferente:
cv::Mat inFrame; // Original (non-empty) image
cv::Mat mask; // Original (non-empty) mask
// ...
cv::Mat outFrame; // Result output
inFrame.copyTo(outFrame, mask);
No aplicas una máscara binaria a una imagen. Usted (opcionalmente) utiliza una máscara binaria en una llamada de función de procesamiento para indicar a la función qué píxeles de la imagen desea procesar. Si estoy malinterpretando completamente su pregunta, debe agregar más detalles para aclarar.
Puede usar la máscara para copiar solo la región de interés de una imagen original a una de destino:
cvCopy(origImage,destImage,mask);
donde mask
debería ser una matriz de un solo canal de 8 bits.
Ver más en la documentación de OpenCV.
Si bien la respuesta de @perrejba es correcta, utiliza las funciones de estilo C heredadas. Como la pregunta está etiquetada como C ++, es posible que desee utilizar un método en su lugar:
inputMat.copyTo(outputMat, maskMat);
Todos los objetos son de tipo cv::Mat
.
Tenga en cuenta que el enmascaramiento es binario. Cualquier valor distinto de cero en la máscara se interpreta como ''hacer copia''. Incluso si la máscara es una imagen en escala de grises.
También tenga en cuenta que la función .copyTo () no borra la salida antes de copiar.
Si desea alterar permanentemente la imagen original, tiene que hacer una copia / clonación / asignación adicional. La función copyTo () no está definida para la superposición de imágenes de entrada / salida. Así que no puedes usar la misma imagen como entrada y salida.