gpt4 book ai didi

c++ - 从 C++ 中的像素值数组创建视频

转载 作者:行者123 更新时间:2023-12-01 14:15:21 26 4
gpt4 key购买 nike

有谁知道将一系列像素值保存到视频中的方法?目前我正在使用 Cimg 来可视化一个简单的 n 体模拟,虽然我可以将每次迭代保存到图像文件中,但这非常慢。任何有关处理视频的类似库的建议将不胜感激。本质上,我只想将我创建的 Cimg 窗口中显示的内容记录到视频文件中。该程序是用 C++ 编写的,在 linux 上,用 g++ 编译。
我可以运行模拟并使用屏幕捕获软件记录它运行的事实似乎意味着它是可能的,但我想要一个更整洁的解决方案。

最佳答案

我今天正在玩这个,并认为我会分享我的结果。您可以从 输出原始 RGB 视频CImg 然后使用 ffmpeg 把它编码成这样的视频:

#include <iostream>
#include "CImg.h"

using namespace std;
using namespace cimg_library;

int main()
{
const unsigned int width=1024;
const unsigned int height=768;

// Basic frame we will draw in
CImg<unsigned char> image(width,height,1,3);

unsigned char magenta[] = {255,0,255};

// We are going to output 300 frames of 1024x768 RGB raw video
// ... making a 10s long video at 30fps
int radius=100;
int cx=100;
int cy=100;
for(int frame=0;frame<300;frame++){
// Start with black - it shows fewer stains ;-)
image.fill(0);
image.draw_circle(cx,cy,radius,magenta);

// Move and re-colour circle
cx+=2; cy++; if(magenta[1]!=255){magenta[1]++;}

// Output to ffmpeg to make video, in planar GBR format
// i.e. run program like this
// ./main | ffmpeg -y -f rawvideo -pixel_format gbrp -video_size 1024x768 -i - -c:v h264 -pix_fmt yuv420p video.mov
char* s=reinterpret_cast<char*>(image.data()+(width*height)); // Get start of G plane
std::cout.write(s,width*height); // Output it
s=reinterpret_cast<char*>(image.data()+2*(width*height)); // Get start of B plane
std::cout.write(s,width*height); // Output it
s=reinterpret_cast<char*>(image.data()); // Get start of R plane
std::cout.write(s,width*height); // Output it
}
}
我想我不会去好莱坞,因为视频不是很令人兴奋!
enter image description here
像这样运行上面的代码来制作视频:
./main | ffmpeg -y -f rawvideo -pixel_format gbrp -video_size 1024x768 -i - -c:v h264 -pix_fmt yuv420p video.mov

注1
要意识到的是 CImg 将数据存储在平面配置中,这意味着首先是所有红色像素,然后是所有绿色像素,然后是所有蓝色像素——所有这些都没有任何填充或空格。
想象一下 CImg 中的 4x4 图像(16 像素):
RRRRRRRRRRRRRRRR GGGGGGGGGGGGGGGG BBBBBBBBBBBBBBBB
与常规 RGB 数据不同,后者将存储相同的图像:
RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB RGB 
因此,您可以将所有数据打乱并重新格式化并传递给 ffmpeg -pixel_fmt rgb24 ,或者像我一样做并在 中输出CImg 的平面格式并选择匹配的 -pixel_fmt gbrp (其中 p 表示“平面”)。您只需要以正确的 B、G、R 顺序输出平面。另见 注4 .

注2
我选择做3 write() s,每个颜色平面一个,为了演示的清晰起见,使用带有 writev() 的“聚集写入”会更有效, 所以这:
char* s=reinterpret_cast<char*>(image.data()+(width*height));   // Get start of G plane
std::cout.write(s,width*height); // Output it
s=reinterpret_cast<char*>(image.data()+2*(width*height)); // Get start of B plane
std::cout.write(s,width*height); // Output it
s=reinterpret_cast<char*>(image.data()); // Get start of R plane
std::cout.write(s,width*height);
会变成这样:
struct iovec iov[3];
ssize_t nwritten;

iov[0].iov_base = reinterpret_cast<char*>(image.data()+(width*height))
iov[0].iov_len = width*height;
iov[1].iov_base = reinterpret_cast<char*>(image.data()+2*(width*height));
iov[1].iov_len = width*height;
iov[2].iov_base = reinterpret_cast<char*>(image.data());
iov[2].iov_len = width*height;

nwritten = writev(STDOUT_FILENO,iov,3);

注3
我用了 -c:v h264 -pix_fmt yuv420p使视频与 Apple 的 兼容快速时间 在我的 Mac 上,但无论如何您都可以轻松更改输出 - 更难的部分是获取 之间的接口(interface)CImg fmpeg 对。

注4
如果你想打乱数据并将其写入 ffmpeg 非平面( -pixel_fmt rgb ),我最初是这样做的,代码是这样的:
// Outside main loop
unsigned char* BIP = new unsigned char[width*height*3];
unsigned char *d,*r,*g,*b;

...
...

// Now output it...
// ... remember CImg is band-interleaved by plane RRRRRR GGGGGG BBBBBB
// ... not band-interleaved by pixel RGB RGB RGB RGB
r=image.data(); // Start of R plane in CImg image
g=r+(width*height); // Start of G plane in CImg image
b=g+(width*height); // Start of B plane in CImg image
d=BIP; // Destination buffer in RGB order
for(int i=0;i<width*height;i++){
*d++=*r++;
*d++=*g++;
*d++=*b++;
}
// Output to ffmpeg to make video, i.e. run program like this
// ./main | ffmpeg -y -f rawvideo -pixel_format rgb24 -video_size 1024x768 -i - -c:v h264 -pix_fmt yuv420p video.mov
std::cout.write(reinterpret_cast<char*>(BIP),width*height*3);
理论上,你可以用 来做到这一点。 CImg permute_axes()方法,但我没有成功。

关于c++ - 从 C++ 中的像素值数组创建视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24228728/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com