Can we convert cv::Mat to NvBuffer

Hi,
As the title said, can we convert cv::Mat to NvBuffer? If we can, could you please give me some examples? Thanks a lot!

You may try converting your cv::Mat into a NvBuffer supported fromat mat such as BGRx or RGBA and use Raw2NvBuffer.
I can’t provide an example, but you may have a look to nvvidconv sources for further details.

Thanks for your reply! And I tried with what you mentioned. However, the image became some strips and lines after converting back to cv::mat. Could you please have a look at my code below to see if I did something wrong? Thanks!

        cv::Mat bgrImg = cv::imread(imagePath, cv::IMREAD_GRAYSCALE);
        cv::Mat continuousRGBA;
        cv::cvtColor(bgrImg, continuousRGBA, cv::COLOR_GRAY2RGBA);
        unsigned char *data = continuousRGBA.data;
        // cv::cvtColor(continuousRGBA, image, cv::COLOR_RGBA2GRAY, 1); // it works normally here

        int dmaFd;
        if (!createNvBuffer(bgrImg.cols, bgrImg.rows, &dmaFd)) {
            throw std::runtime_error("Failed to create resize NvBuffer");
        }
        int res = Raw2NvBuffer(data, 0, bgrImg.cols, bgrImg.rows, dmaFd);
        if (res == 0) {
            std::cout<<"it works well "<<dmaFd<<std::endl;
        }
        cv::Mat image = convertNvBufferToCvMat(dmaFd);

Quickly tried the following code, seems working but I didn’t further check byte ordering:

#include <opencv2/opencv.hpp>
#include <nvbuf_utils.h>

int main() {

	/* Read image from file */
	cv::Mat bgrMat = cv::imread("test.png");
	
	/* Convert it into 32 bits pixels such as BGRA */
	cv::Mat bgraMat;
	cv::cvtColor(bgrMat, bgraMat, cv::COLOR_BGR2BGRA);
	
	/* Display input and wait for key press */
	cv::imshow("Input to BGRA", bgraMat);
	cv::waitKey(-1);

	/* Create a NvBuffer for same size with format ARGB32 */
	int dmaFd;
	NvBufferCreateParams params = {
		.width       = bgraMat.cols,
		.height      = bgraMat.rows, 
		.payloadType = NvBufferPayload_SurfArray,
		.memsize     = (4 * bgraMat.cols * bgraMat.rows),
		.colorFormat = NvBufferColorFormat_ARGB32,
		.nvbuf_tag   = NvBufferTag_NONE 
	};
	if (NvBufferCreateEx(&dmaFd, &params)) {
		std::cerr << "Create buffer failed\n";
		return(-1);
	}
	
	/* Copy cpu buffer into NVMM */
	if (Raw2NvBuffer(bgraMat.data, 0, bgraMat.cols, bgraMat.rows, dmaFd)) {
		std::cerr << "Raw2NvBuffer failed\n";
		return(-2);
	}
	
	/* Do some NvBuffer processing here.. */

	/* Copy NvBuffer back into system memory */
	cv::Mat bgraMat2(bgraMat.rows, bgraMat.cols, CV_8UC4);
	if (NvBuffer2Raw(dmaFd, 0, bgraMat2.cols, bgraMat2.rows, bgraMat2.data)) {
		std::cerr << "NvBuffer2Raw failed\n";
		return(-3);
	}

	NvBufferDestroy(dmaFd);

	cv::imshow("BGRA read back", bgraMat2);
	cv::waitKey(-1);


	return 0;
}

You may try this as a starting point and report further issues.

Thanks a bunch! It works! Seems like I used wrong NvBufferColorFormat.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.