-
捕获视频并保存到本地文件:test.raw
sudo somagic-capture -i 1 | mplayer -vf yadif,screenshot -demuxer rawvideo -rawvideo "pal:format=uyvy:fps=25" -aspect 4:3 -
从这条命领可以得到两个信息:
-
-rawvideo “pal:format=uyuv:fps=25” -aspect 4:3
表明test.raw文件采集的原始格式是720x576@25fps的视频信号,保存格式是UYUV。
-
命令最后的”-“符号
表示以上一条命令在终端的输出作为本命令的输入,这一点以后可以利用。
-
应该怎么读取test.raw
UYUV的存储格式是:u12,y1,v12,y2;u34,y3,v34,y4;…
每一帧大小是720x576像素,按照UYUV的格式存储(4字节表达2个像素),每一帧大小是829440字节。
test.raw文件大小是170035200字节,总共包含205帧。
YUV颜色空间到RGB颜色空间的转换公式是:
r = y + 1.13983 * (v - 128.0);
g = y - 0.39465 * (u - 128.0) - 0.58060 * (v - 128.0);
b = y + 2.03211 * (u - 128.0);
-
源代码1
1 #include <iostream>
2 #include <opencv2/opencv.hpp>
3 #include <cstdio>
4
5 int main(int argc, char **argv) {
6 FILE *fp = fopen(argv[1], "rb");
7 if (!fp) {
8 std::cout << "不能加载:" << argv[1] << std::endl;
9 return 1;
10 }
11
12 unsigned char buf[829440];
13 unsigned char val;
14 char title[100];
15 while (!feof(fp)) {
16 sprintf(title, "%ld", ftell(fp) / 829440 + 1);
17
18 for (int i = 0; i < 829440; ++i) {
19 fscanf(fp, "%c", &val);
20 buf[i] = val;
21 }
22
23 /// 720x576@25, 720x480@30
24 cv::Mat bgr[3];
25 bgr[0] = cv::Mat(576, 720, CV_8UC1, cv::Scalar(0));
26 bgr[1] = cv::Mat(576, 720, CV_8UC1, cv::Scalar(0));
27 bgr[2] = cv::Mat(576, 720, CV_8UC1, cv::Scalar(0));
28 int row = 0;
29 int col = 0;
30 unsigned char y;
31 unsigned char u;
32 unsigned char v;
33 for (int i = 0; i < 829440; i = i + 4) {
34 u = buf[i];
35 y = buf[i + 1];
36 v = buf[i + 2];
37
38 double r = (double)y + 1.13983 * ((double)v - 128.0);
39 double g = (double)y - 0.39465 * ((double)u - 128.0) - 0.58060 * ((double)v - 128.0);
40 double b = (double)y + 2.03211 * ((double)u - 128.0);
41 bgr[0].at<unsigned char>(row, col) = cv::saturate_cast<unsigned char>(b);
42 bgr[1].at<unsigned char>(row, col) = cv::saturate_cast<unsigned char>(g);
43 bgr[2].at<unsigned char>(row, col) = cv::saturate_cast<unsigned char>(r);
44
45 y = buf[i + 3];
46
47 r = (double)y + 1.13983 * ((double)v - 128.0);
48 g = (double)y - 0.39465 * ((double)u - 128.0) - 0.58060 * ((double)v - 128.0);
49 b = (double)y + 2.03211 * ((double)u - 128.0);
50 bgr[0].at<unsigned char>(row, col + 1) = cv::saturate_cast<unsigned char>(b);
51 bgr[1].at<unsigned char>(row, col + 1) = cv::saturate_cast<unsigned char>(g);
52 bgr[2].at<unsigned char>(row, col + 1) = cv::saturate_cast<unsigned char>(r);
53
54 col = col + 2;
55 if (col >= 720) {
56 col = 0;
57 row = row + 1;
58 }
59 }
60 cv::Mat src;
61 cv::merge(bgr, 3, src);
62
63 cv::putText(src, title, cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(255, 255 ,0));
64
65 cv::imshow("img", src);
66 cv::waitKey(40);
67 }
68
69 return 0;
70 }
调试命令:
Debug/test ./test.raw
这里相当于离线调试。
- 源代码2
1 int main(int argc, char **argv) {
2 // FILE *fp = fopen(argv[1], "rb");
3 // if (!fp) {
4 // std::cout << "不能加载:" << argv[1] << std::endl;
5 // return 1;
6 // }
7
8 unsigned char buf[829440];
9 unsigned char val;
10 char title[10];
11 // while (!feof(fp)) {
12 int counter = 0;
13 while (1) {
14 // sprintf(title, "%ld", ftell(fp) / 829440 + 1);
15 sprintf(title, "%d", counter++);
16
17 for (int i = 0; i < 829440; ++i) {
18 // fscanf(fp, "%c", &val);
19 scanf("%c", &val);
20 buf[i] = val;
21 }
22 ...
调试命令:
sudo somagic-capture -i 1 | Debug/test -
这里相当于在线调试。
-
存在问题
效率极端低下,每帧的解析过程消耗时间有长有短,回放画面时快时慢。