摄像头图像,jpg格式,vc++目录操作

来源:互联网 发布:深圳开网络出租屋 编辑:程序博客网 时间:2024/06/05 01:06

摄像头接到开始命令后开始采集图像,并将图像压缩为JPEG格式,摄像头采取分包传递的方式,每传递一个包后,只有上位机得到确认命令(即摄像头取图命令)后,摄像头才开始传下一个包,直到图像传递完成。

摄像头编号设置命令(由上位机发给视频模块

   (以下数据一般以16进制,即 0x 开头表示)

包头

(2字节)

命令码

(1字节)

位置编号

(1字节)

数据(4字节)

包尾

(2字节)

摄像头编号

(小端模式,2字节)

该摄像头以后将要使用的编号

0x40 0x40

0x60

0x5A

0xFF 0xFF

0xFF 0xFF

0x0D 0x0A

说明1:每个摄像头都有一个编号,当摄像头收到的数据域内的摄像头编号与自己相一致时才响应该命令,但如果该数据域内的摄像头编号为0xFFFF,表示通用编号,任何摄像头都要响应该命令。

说明2:该命令中的位置编号无实际意义;

说明3:摄像头收到该命令后将该编号存入非易失的存储器中,以后将只响应摄像头编号与新编号及通用编号相同的命令。

摄像头开始拍摄命令(由上位机发给视频模块

包头

(2字节)

命令码

(1字节)

照片大小

(1字节)

数据(4字节)

包尾

(2字节)

摄像头编号

(小端模式)

图像包大小

(小端模式)

0x40 0x40

0x61

0x80(160*128)

0x81(320*240)

0x82(640*480)

0xFF 0xFF

0xFF 0xFF 

0x0D 0x0A

 

说明1:当摄像头收到的数据域内的摄像头编号与自己相一致时才响应该命令,但如果该数据域内的摄像头编号为0xFFFF,表示通用编号,任何摄像头都要响应该命令。

说明2:摄像头收到该命令后返回所拍图像数据的第一帧数据。

摄像头取图命令(由上位机发给视频模块

包头

(2字节)

命令码

(1字节)

照片大小

(1字节)

数据(4字节)

包尾

(2字节)

摄像头编号

(小端模式)

图像位置编号

(小端模式)

0x40 0x40

0x62

0x80(160*128)

0x81(320*240)

0x82(640*480)

0xFF 0xFF

0xFF 0xFF

0x0D 0x0A

说明1:当摄像头收到的数据域内的摄像头编号与自己相一致时才响应该命令,但如果该数据域内的摄像头编号为0xFFFF,表示通用编号,任何摄像头都要响应该命令。

说明2:当数据域内的图像位置编号为0xFF 0xFF表示按顺序取图,摄像头每次传送某位置的数据后,会自动把位置编号加一(位置编号从0开始);

说明3:当数据域内的位置编号不为0xFF 0xFF表示取固定位置的图像数据,主机端每次索要某位置的数据后,主机端需自己把位置编号加一;

说明3:照片大小字节无意义,但内容必须为0x81、0x82或0x83

 摄像头上传图像数据包格式(由视频模块发给上位机)

1)   

包头

位置

帧的大小

256

图像数据

校验和

结束

40 40 63

KK KK

00  02

FF

FF D8 ……

一  个

字  节

0D 0A

XX  XX

……FF D9

 

小端

小端

 

所有数据累加―――校验和

举例:0x40 0x40 0x63 0xKK 0xKK 0xXX 0xXX 0xFF 0xPP …… 0xVV 0x0D 0x0A

2)包头:0x40 0x40 0x63

3)数据开始传送位置:用两个字节表示:0xKK 0xKK 第一帧数据表示为0x00 0x00。上位机每发送一次

0x40 0x40 0x62 0x81 0xFF 0xFF 0xFF 0xFF 0x0D 0x0A,摄像头位置加1,直到数据传送完毕。

4)数据帧的大小:用两个字节表示:0xXX 0xXX  表示为0xXX 0Xxx 发送数据包;当数据包的大小不等于0xXX 0xXX 时,或图像数据的最后两个字节为0xFFD9时,说明数据传送到了最后一包数据,数据帧的大小和拍摄图片的大小有关。

数据内容:开始标志: FF D8  结束标志:FF D9 。 数据传送模式FF D8 ……0xVV 0D 0A,……FF D9 0xVV 0D 0A  。其中0xVV为校验和 。校验和的算法:图像数据累加和

 

注意:开始标志: FF D8 结束标志:FF D9 以及这两个标志之间的内容正好是jpg图像的格式,不得分割。

jpeg文件格式:

-- 文件头(2bytes)ff,d8(SOI)

-- 任意数量的段,见后

--文件结束(2bytes)ff,d9(EOI)

段的格式:

-- header(4bytes)

        ff 段标识

        n 段的类型(1byte)

        sh,sl  该段长度,包括这两个字节,但不包括前面的ff和n

                    注意:长度不是intel序,而是motorola序,高字节在前,低字节在后

-- 该段的内容,最多65533字节

 

将数据写入文件时,文件一定要以二进制形式创建,写文件有文本格式和二进制格式之分,ios::binary就是二进制, 它与文本格式的差别在于,文本格式会增加一些格式上的信息,比如换行'\n'用文本输出是两个字节0x0Ah,0x0Dh. 而如用二进制输出则是0x0Ah。这样才能保证图像文件写入正确。

ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间;
在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O。
void open(const char* filename,int mode,int access);
read(unsigned char *buf,int num); 
write(const unsigned char *buf,int num); 
C++ I/O系统管理两个与一个文件相联系的指针。一个是读指针,它说明输入操作在文件中的位置;另一个是写指针,它下次写操作的位置。每次执行输入或输出时,相应的指针自动变化。所以,C++的文件定位分为读位置和写位置的定位,对应的成员函数是seekg()和seekp()。seekg()是设置读位置, seekp是设置写位置。它们最通用的形式如下:
    istream &seekg(streamoff offset,seek_dir origin);
    ostream &seekp(streamoff offset,seek_dir origin);
  streamoff定义于 iostream.h 中,定义有偏移量 offset 所能取得的最大值,seek_dir 表示移动的基准位置,是一个有以下值的枚举:
ios::beg:  文件开头
ios::cur:  文件当前位置
ios::end:  文件结尾
  这两个函数一般用于二进制文件,因为文本文件会因为系统对字符的解释而可能与预想的值不同。

/* 目录是否存在的检查 */
BOOL FolderExist(CString strPath)
{
     WIN32_FIND_DATA   wfd;
     BOOL rValue = FALSE;
     HANDLE hFind = FindFirstFile(strPath, &wfd);
    if ((hFind != INVALID_HANDLE_VALUE) && (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
    {
        rValue = TRUE;   
     }
     FindClose(hFind);
    return rValule;
}

/* 文件存在性检查 */
BOOL FileExist(CString strFileName)
{
    CFileFind fFind;
    return fFind.FindFile(strFileName);
}

创建目录:
BOOL CreateFolder(CString strPath)
{
     SECURITY_ATTRIBUTES attrib;
     attrib.bInheritHandle = FALSE;
     attrib.lpSecurityDescriptor = NULL;
     attrib.nLength =sizeof(SECURITY_ATTRIBUTES);
    //上面定义的属性可以省略。 直接return ::CreateDirectory( path, NULL); 即可
     return ::CreateDirectory( strPath, &attrib);
}

原创粉丝点击