J’essaie de copier les données d’un cv::cuda::GpuMat
dans une variable uint8_t*
qui doit être utilisée dans un kernel.
Le GpuMat contient des données d’image de résolution 752×480 et de type CV_8UC1. Voici l’exemple de code:
uint8_t *imgPtr; cv::Mat left, downloadedLeft; cv::cuda::GpuMat gpuLeft; left = imread("leftview.jpg", cv::IMREAD_GRAYSCALE); gpuLeft.upload(left); cudaMalloc((void **)&imgPtr, sizeof(uint8_t)*gpuLeft.rows*gpuLeft.cols); cudaMemcpyAsync(imgPtr, gpuLeft.ptr(), sizeof(uint8_t)*gpuLeft.rows*gpuLeft.cols, cudaMemcpyDeviceToDevice); // following code is just for testing and visualization... cv::cuda::GpuMat gpuImg(left.rows, left.cols, left.type(), imgPtr); gpuImg.download(downloadedLeft); imshow ("test", downloadedLeft); waitKey(0);
Mais la sortie n’est pas comme prévu. Voici les images d’entrée et de sortie, respectivement.
CONTRIBUTION
SORTIE
J’ai essayé de donner le cv::Mat
source au cudaMemcpy
. Cela semble bien fonctionner. Le problème semble être avec les cv::cuda::GpuMat
et cudaMemcpy
. Une question similaire est discutée ici
De plus, si l’image est 256 ou 512, le programme semble fonctionner correctement.
Qu’est-ce qui me manque? Que faut-il faire pour que l’image 752×480 fonctionne correctement?
OpenCV GpuMat utilise le stockage ssortingded (ainsi, l’image n’est pas stockée de manière contiguë dans la mémoire). En bref, votre exemple échoue dans la plupart des cas car
À ma lecture de la documentation, vous voulez probablement quelque chose comme ceci:
uint8_t *imgPtr; cv::Mat left, downloadedLeft; cv::cuda::GpuMat gpuLeft; left = imread("leftview.jpg", cv::IMREAD_GRAYSCALE); gpuLeft.upload(left); cudaMalloc((void **)&imgPtr, gpuLeft.rows*gpuLeft.step); cudaMemcpyAsync(imgPtr, gpuLeft.ptr(), gpuLeft.rows*gpuLeft.step, cudaMemcpyDeviceToDevice); // following code is just for testing and visualization... cv::cuda::GpuMat gpuImg(left.rows, left.cols, left.type(), imgPtr, gpuLeft.step); gpuImg.download(downloadedLeft); imshow ("test", downloadedLeft); waitKey(0);
[Écrit par quelqu’un qui n’a jamais utilisé OpenCV, ni compilé ni testé, utilise à ses risques et périls]
La seule fois où votre code fonctionnerait correctement serait lorsque le pas de la ligne du GpuMat était le même que le nombre de colonnes multiplié par la taille du type stocké dans la masortingce. Ce sont probablement des images dont la taille correspond à une puissance arrondie de deux.