66 votes

Comment recadrer un CvMat dans OpenCV ?

J'ai une image convertie en CvMat Matrice dire CVMat source . Une fois que j'obtiens une région d'intérêt de source je veux que le reste de l'algorithme soit appliqué à cette région d'intérêt uniquement. Pour cela, je pense que je devrai en quelque sorte recadrer la source ce que je suis incapable de faire. Existe-t-il une méthode ou une fonction qui pourrait recadrer une CvMat et renvoyer une autre matrice CvMat recadrée ? Merci.

146voto

Chris Points 2473

OpenCV a des fonctions de région d'intérêt que vous pouvez trouver utiles. Si vous utilisez le cv::Mat vous pouvez utiliser quelque chose comme ce qui suit.

 // 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);

Documentation pour extraire la sous-image

45voto

MMH Points 1549

Je sais que cette question est déjà résolue... mais il existe un moyen très simple de recadrer. vous pouvez simplement le faire en une seule ligne-

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

23voto

pacongfar Points 321

Pour obtenir de meilleurs résultats et une meilleure robustesse contre différents types de matrices, vous pouvez faire ceci en plus de la première réponse, qui copie les données :

 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);

10voto

Reed Richards Points 815

Pour créer une copie du recadrage souhaité, nous pouvons procéder comme suit,

 // 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();

1voto

strudelheist Points 49

Je comprends que cette question a reçu une réponse, mais peut-être que cela pourrait être utile à quelqu'un...

Si vous souhaitez copier les données dans un objet cv::Mat séparé, vous pouvez utiliser une fonction similaire à celle-ci :

 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];
        }
    }
}

Il serait important de noter que cela ne fonctionnerait correctement que sur des images monocanal .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X