web-dev-qa-db-fra.com

Comment recadrer un CvMat dans OpenCV?

J'ai une image convertie en CvMat Matrix dire CVMat source. Une fois que je reçois une région d'intérêt de source, je souhaite que le reste de l'algorithme ne soit appliqué qu'à cette région d'intérêt. Pour cela, je pense que je devrai rogner d’une manière ou d’une autre la matrice source pour laquelle je suis incapable de le faire. Existe-t-il une méthode ou une fonction permettant de rogner une matrice CvMat et de renvoyer une autre matrice rognée CvMat? Merci.

49
Waqar

OpenCV a des fonctions de régions d’intérêt que vous pouvez trouver utiles. Si vous utilisez le cv::Mat alors 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 une sous-image

111
Chris

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

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

Pour obtenir de meilleurs résultats et une meilleure robustesse face aux différents types de matrices, vous pouvez le faire 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);
17
pacongfar

Pour créer une copie du recadrage que nous voulons, 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();
3
Reed Richards

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 séparé cv :: Mat , 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 images monocanal.

0
strudelheist