Hello,
[My Environment]
- Jetson TK1
- Jetpack 3.1 (Linux 4 Tegra 21.8 = Ubuntu 14.04)
- OpenCV4Tegra 2.4.13
- ZED SDK 1.1.1
[My Problem]
I’m encountering an issue similar to the one described here: Cannot write video frame using OpenCV VideoWriter. My code is supposed to record video, but it only outputs a 5.7KB avi file, indicating that the frames are not being captured correctly.
[My Pseudo Code]
I’ve trimmed the unnecessary code and simplified it for clarity.
// Standard includes
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
// ZED includes
#include <zed/Mat.hpp>
#include <zed/Camera.hpp>
#include <zed/utils/GlobalDefine.hpp>
// OpenCV includes
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <ctime> // For time functions
// CUDA functions include
#include "kernel.cuh"
using namespace sl::zed;
using namespace std;
int main(int argc, char **argv) {
// Initialize ZED camera
Camera* zed = new Camera(HD720, 15);
InitParams parameters;
parameters.unit = UNIT::METER;
ERRCODE err = zed->init(parameters);
if (err != SUCCESS) {
std::cerr << "Error initializing ZED camera: " << errcode2str(err) << std::endl;
delete zed;
return 1;
}
// Initialize CUDA memory
CPU_obstacleCounts = (int*)malloc(sizeof(int) * 3);
*CPU_obstacleCounts = 0;
*(CPU_obstacleCounts + 1) = 0;
*(CPU_obstacleCounts + 2) = 0;
int* GPU_obstacleCounts;
cudaMalloc((void**)&GPU_obstacleCounts, 3 * sizeof(int));
cudaMemcpy(GPU_obstacleCounts, CPU_obstacleCounts, 3 * sizeof(int), cudaMemcpyHostToDevice);
// ZED OpenCV Variables
int width = zed->getImageSize().width;
int height = zed->getImageSize().height;
// Create and allocate GPU memory for the image matrix
Mat imageCropp;
imageCropp.data = (unsigned char*)nppiMalloc_8u_C4(width, height, &imageCropp.step);
imageCropp.setUp(width, height, 4, sl::zed::UCHAR, GPU);
// Create and allocate GPU memory for the mask matrix
Mat imageCheckerboard;
imageCheckerboard.data = (unsigned char*)nppiMalloc_8u_C4(width, height, &imageCheckerboard.step);
imageCheckerboard.setUp(width, height, 4, sl::zed::UCHAR, GPU);
// Compute the checkerboard only once; it will be used to mask the invalid area
cuCreateCheckerboard(imageCheckerboard);
// Create a CPU image for display purposes
cv::Mat imDisplay(height, width, CV_8UC4);
// Initialize VideoWriter to record video
std::string outputVideo = "output_" + getCurrentDateTime() + ".avi"; // Output file name
int codec = CV_FOURCC('M', 'J', 'P', 'G'); // Codec MJPEG = .avi
int fps = 15;
cv::VideoWriter videoWriter(outputVideo, codec, fps, cv::Size(width, height));
if (!videoWriter.isOpened()) {
std::cout << "Could not open the output video file for writing." << std::endl;
return -1;
}
float distCut = 1.0;
// Main processing loop
while (true) {
bool res = zed->grab(STANDARD);
Mat imageLeftGPU = zed->retrieveImage_gpu(LEFT);
Mat depthGPU = zed->retrieveMeasure_gpu(DEPTH);
cuDetectObstacleByDepth(depthGPU, imageLeftGPU, imageCropp, imageCheckerboard, distCut, GPU_obstacleCounts);
// Copy processed image from GPU to CPU
cudaMemcpy2D((uchar*)imDisplay.data, imDisplay.step, (Npp8u*)imageCropp.data, imageCropp.step, imageCropp.getWidthByte(), imageCropp.height, cudaMemcpyDeviceToHost);
cudaMemcpy(CPU_obstacleCounts, GPU_obstacleCounts, 3 * sizeof(int), cudaMemcpyDeviceToHost);
videoWriter.write(imDisplay); // Video recording
cv::imshow("Obstacle Display", imDisplay);
char key = cv::waitKey(1);
if (key == 'q' || key == 'Q') {
std::cout << "q pressed. Breaking." << std::endl;
break;
}
cudaMemset(GPU_obstacleCounts, 0, 3 * sizeof(int)); // Clear GPU data
}
std::cout << "[1] Loop exited." << std::endl;
// Cleanup
videoWriter.release(); // Release the video writer
free(CPU_obstacleCounts);
cudaFree(GPU_obstacleCounts);
std::cout << "[2] Obstacle counts memory freed." << std::endl;
imDisplay.release();
std::cout << "[3] OpenCV Image Display released." << std::endl;
imageCropp.deallocate();
imageCheckerboard.deallocate();
delete zed;
std::cout << "[4] All dynamic memory deallocated successfully." << std::endl;
return 0;
}
[What I’ve Tried]
In the code, I’ve set the codec to CV_FOURCC('M','J','P','G')
. I’ve also tried other codecs like ‘XVID’, ‘DIVX’, ‘H264’, and ‘MP4V’, but they didn’t work. I installed VLC media player and the issue persisted. Additionally, I installed FFmpeg codecs using the command:
sudo apt-get install libavcodec-dev libavdevice-dev libavfilter-dev libavformat-dev libavl-dev libavresample-dev libavutil-dev
as suggested in this link: How to install FFmpeg on Jetson TX1, but it didn’t resolve the issue.