We have a QT based C++ application running on windows.
We are reading a data file which provides us images which we save in QPixmap variable.
When the data file is read in for loop huge number of image some 900 is received which we display in QLabel.
We want to save the images in .avi video for which we are using OpenCV API.
QVector<QPixmap> imageVector;
void saveImageInVector(QPixmap* imagePixmap)
{
static long imageCounter = 0;
....
QPixmap localImagePixmap = *imagePixmap;
imageVector.insert(imageCounter, localImagePixmap);
imageCounter++;
....
}
Function saveImageInVector() is called repeatedly in a loop and is used to save all the images in a vector.
Next when all the images are added in a vector we call function createVideoFromImages() to save the images in vector to an avi file.
For this first we write the images on hard disk and then read the image from hard disk and save it avi file.
CvVideoWriter *openCvAviWriter;
void createVideoFromImages()
int imageVectorSize = imageVector.size();
int imageFramesPerSecond = imageVectorSize/(videoEndTime - videoStartTime); // frame is dependent on length of video
for (long i = 0; i < imageVectorSize; ++i)
{
QPixmap forPixmapImage = imageVector.at(i);
QPixmap* OriginalPixmaps;
OriginalPixmaps = &forPixmapImage;
QImage qSingleImage = OriginalPixmaps->toImage(); // Convert QPixmap to QImage
if(openCvAviWriter == 0) // On first image this will create the video writer handler
{
QString vidFileNamePreFix;
openCvAviWriter = cvCreateVideoWriter("c:myVideo.avi", CV_FOURCC_DEFAULT, imageFramesPerSecond, cvSize(qSingeImage.width(), qSingleImage.height()), AVI_COLOR_IMAGE);
imageFileNum = 0;
}
if(openCvAviWriter) // from second image onwards keep saving images to disk and from disk ther image is read and added to the video
{
// from second image onwards keep saving images to disk
QString videoPath = QString("image_") + QString(QString::number(imageFileNum)) + QString(".png");
OriginalPixmaps->save(videoPath, AVI_VIZ_IMAGE_FILE_TYPE);
imageFileNum++;
// from disk read the image and add to the video
IplImage* imgSave = 0;
imgSave = cvLoadImage(videoPath.toStdString().c_str()); // // <<<<<<<<<<======= takes time
f = cvWriteFrame(openCvAviWriter, imgSave); // <<<<<<<<<<======= takes time
}
}
imageVector.erase(imageVector.begin(),imageVector.end());
Video created is of good quality.
But the above process of saving the video is taking hell lot of time.
For instance for a 1 minute video it takes 15 minutes to save the images in video using the above code.
So we decided NOT saving the image on disk but directly saving it in the avi video file.
Also set the frame rate fixed to some value like 10.
This process takes not more then 1 minutes but the video is very badly distorted.
if (!imageVector.isEmpty())
{
int imageFramesPerSecond = 10; // Set the frame rate to 10 fps
QSize imageSize = imageVector.first().size(); // suppose all images are of same size
CvVideoWriter* openCvAviWriter = cvCreateVideoWriter(vizVidWriterPath.toStdString().c_str(), CV_FOURCC_DEFAULT, imageFramesPerSecond, cvSize(imageSize.width(), imageSize.height()), AVI_COLOR_IMAGE);
if (openCvAviWriter)
{
for (const QPixmap& pixmap : imageVector)
{
QImage qImageObj = pixmap.toImage();
if (!qImageObj.isNull())
{
IplImage* imgNew = cvCreateImage(cvSize(qImageObj.width(), qImageObj.height()), IPL_DEPTH_8U, 4);
memcpy(imgNew->imageData, qImageObj.bits(), qImageObj.byteCount());
cvWriteFrame(openCvAviWriter, imgNew);
cvReleaseImage(&imgNew);
}
}
cvReleaseVideoWriter(&openCvAviWriter);
openCvAviWriter = NULL;
}
}
Here the image is badly distorted and location of contents of image changed.
What might be the cause of the issue and how to save the images in video in very short time?