library copyto convertto opencv opencv-mat

copyto - Cómo recortar un CvMat en OpenCV?



opencv mat rgb (6)

Tengo una imagen convertida en CvMat Matrix, dice CVMat source . Una vez que obtenga una región de interés de la source , quiero que el resto del algoritmo se aplique únicamente a esa región de interés. Para eso, creo que tendré que recortar de algún modo la matriz de source , lo que no puedo hacer. ¿Hay algún método o función que pueda recortar una Matriz CvMat y devolver otra matriz recortada CvMat ? Gracias.


Entiendo que esta pregunta ha sido respondida, pero quizás esto podría ser útil para alguien ...

Si desea copiar los datos en un objeto cv :: Mat por separado, podría utilizar una función similar a esta:

void ExtractROI(Mat& inImage, Mat& outImage, Rect roi){ /* Create the image */ outImage = Mat(roi.height, roi.width, inImage.type(), Scalar(0)); /* Populate the image */ for (int i = roi.y; i < (roi.y+roi.height); i++){ uchar* inP = inImage.ptr<uchar>(i); uchar* outP = outImage.ptr<uchar>(i-roi.y); for (int j = roi.x; j < (roi.x+roi.width); j++){ outP[j-roi.x] = inP[j]; } } }

Sería importante tener en cuenta que esto solo funcionaría correctamente en imágenes de un solo canal .


OpenCV tiene funciones de región de interés que pueden serle útiles. Si está utilizando cv::Mat , podría usar algo como lo siguiente.

// You mention that you start with a CVMat* imagesource CVMat * imagesource; // Transform it into the C++ cv::Mat format cv::Mat image(imagesource); // Setup a rectangle to define your region of interest cv::Rect myROI(10, 10, 100, 100); // Crop the full image to that image contained by the rectangle myROI // Note that this doesn''t copy the data cv::Mat croppedImage = image(myROI);

Documentación para extraer imágenes secundarias


Para crear una copia del cultivo que queremos, podemos hacer lo siguiente,

// Read img cv::Mat img = cv::imread("imgFileName"); cv::Mat croppedImg; // This line picks out the rectangle from the image // and copies to a new Mat img(cv::Rect(xMin,yMin,xMax-xMin,yMax-yMin)).copyTo(croppedImg); // Display diff cv::imshow( "Original Image", img ); cv::imshow( "Cropped Image", croppedImg); cv::waitKey();


Para obtener mejores resultados y robustez frente a los diferentes tipos de matrices, puede hacer esto además de la primera respuesta, que copie los datos:

cv::Mat source = getYourSource(); // Setup a rectangle to define your region of interest cv::Rect myROI(10, 10, 100, 100); // Crop the full image to that image contained by the rectangle myROI // Note that this doesn''t copy the data cv::Mat croppedRef(source, myROI); cv::Mat cropped; // Copy the data into new matrix croppedRef.copyTo(cropped);


Puede recortar fácilmente una estera usando funciones de OpenCV.

setMouseCallback("Original",mouse_call);

El mouse_call se da a continuación:

void mouse_call(int event,int x,int y,int,void*) { if(event==EVENT_LBUTTONDOWN) { leftDown=true; cor1.x=x; cor1.y=y; cout <<"Corner 1: "<<cor1<<endl; } if(event==EVENT_LBUTTONUP) { if(abs(x-cor1.x)>20&&abs(y-cor1.y)>20) //checking whether the region is too small { leftup=true; cor2.x=x; cor2.y=y; cout<<"Corner 2: "<<cor2<<endl; } else { cout<<"Select a region more than 20 pixels"<<endl; } } if(leftDown==true&&leftup==false) //when the left button is down { Point pt; pt.x=x; pt.y=y; Mat temp_img=img.clone(); rectangle(temp_img,cor1,pt,Scalar(0,0,255)); //drawing a rectangle continuously imshow("Original",temp_img); } if(leftDown==true&&leftup==true) //when the selection is done { box.width=abs(cor1.x-cor2.x); box.height=abs(cor1.y-cor2.y); box.x=min(cor1.x,cor2.x); box.y=min(cor1.y,cor2.y); Mat crop(img,box); //Selecting a ROI(region of interest) from the original pic namedWindow("Cropped Image"); imshow("Cropped Image",crop); //showing the cropped image leftDown=false; leftup=false; } }

Para más detalles, puede visitar el enlace Recortar la imagen usando el mouse


Sé que esta pregunta ya está resuelta ... pero hay una manera muy fácil de cosechar. solo puedes hacerlo en una línea-

Mat cropedImage = fullImage(Rect(X,Y,Width,Height));