|

本帖最后由 精意源码 于 2025-8-8 18:24 编辑
不知道大家遇到需要调用摄像头的情况需要如何处理呢?
一般情况py/c++我会使用CV库,易语言只能上网找模块了,但是易语言的调用摄像头模块效率极低并且相关例子极少,十分不友好!
其次,用py使用cv库编译后文件>50mb,c++没试过但是也不会少到哪去,因为要内嵌CV的DLL库,而这个库是非常大的
c++的优势本身有速度快编译文件小,如果对图像处理需求不大,那么调用CV库就太麻烦且难受了!
所以我开发了这个C++纯API实现调用摄像头
多的不说,直接看编译后的使用例子,
编译器使用 VS2022 ,
1.载入sln文件进入IDE后按shuft+Alt+B即可直接编译(编译文件名以“摄像头C++”为例)
2.在x64\Release文件夹中找到编译后的exe文件
3.在当前文件使用cd导航终端到当前目录
4.输入“摄像头C++.exe”可查看具体命令格式
equipment | # 输出摄像头设备数和名称 | photograph [100|1-99] [cam_index] | # 拍一张PNG(100)或JPG(1-99)照片 将在终端输出base64编码 | photostreams [100|1-99] [cam_index] | # 持续拍PNG(100)或JPG(1-99)照片 将在终端输出base64编码 |
使用示例1:
[Shell] 纯文本查看 复制代码 摄像头C++\x64\Release>摄像头C++ photograph 99 0
解释:用摄像头编号 0 拍摄一张清晰度为99 %的JPG照片
终端会直接拍照并且直接输出base64编码
使用示例2:
摄像头C++\x64\Release>摄像头C++ equipment
检测到摄像头数 :1
摄像头[0]: HP Truevision HD
因为网络问题无法上传附件这边就用lanzy吧,拿了吱一声
代码已经采用模块化,可以通过自己引用函数自定义功能,需要定制私聊我(QQ2157660868),如果反响好我会继续优化,目前仅满足我自己的需求!
https://wwtw.lanzn.com/iBBwm32xqpdi
[md]# 摄像头API集成与使用说明
## 功能简介
本组件基于 DirectShow 封装,支持 Windows 下摄像头采集一帧并保存为 BMP 图片,或直接获取内存中的位图数据。
## 文件说明
- `capture_camera.h`:摄像头API头文件,声明初始化、拍照、释放、获取内存数据等接口。
- `capture_camera.cpp`:摄像头API实现文件。
- `main.cpp`:调用示例,演示如何拍照并保存为 bmp,或获取内存数据后自行保存。
## 集成步骤
1. 将 `capture_camera.h` 和 `capture_camera.cpp` 添加到你的 Visual Studio 项目中。
2. 在你的代码中 `#include "capture_camera.h"`。
3. 链接 `strmiids.lib`,项目属性->链接器->输入->附加依赖项,添加 `strmiids.lib`。
4. 确保项目字符集为“使用多字节字符集”。
## 接口说明
- `void* camera_init();`
初始化摄像头,返回句柄,失败返回 NULL。**只需初始化一次,可多次采集。**
- `int camera_capture(void* handle, const char* filename);`
拍照并保存为 bmp 文件,返回 0 成功,非 0 失败。**可多次调用,无需重复初始化。**
- `unsigned char* camera_capture_buffer(void* handle, int* width, int* height, int* stride);`
拍照并返回 BGR 格式位图数据(不带 BMP 头),成功返回数据指针,失败返回 NULL。宽、高、步长通过参数返回。数据需调用者用 delete[] 释放。**可多次调用。**
- `void camera_release(void* handle);`
释放摄像头资源。
- `int camera_enum_devices(char names[][256], int max_count);`
获取摄像头数量,并可选输出摄像头名称列表(names为char[256]数组,max_count为最大数量,传NULL仅返回数量)。
## 示例代码:获取内存位图数据并保存为 BMP
```cpp
#define _CRT_SECURE_NO_WARNINGS
#include "capture_camera.h"
#include <iostream>
#include <cstdio>
// 保存BGR数据为BMP文件
bool SaveBitmapToFile(unsigned char* pBuffer, int width, int height, int stride, const char* filename) {
BITMAPFILEHEADER bfh = {0};
BITMAPINFOHEADER bih = {0};
bfh.bfType = 0x4d42; // 'BM'
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfSize = bfh.bfOffBits + stride * height;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = width;
bih.biHeight = -height; // 正向
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = BI_RGB;
bih.biSizeImage = stride * height;
FILE* fp = fopen(filename, "wb");
if (!fp) return false;
fwrite(&bfh, sizeof(bfh), 1, fp);
fwrite(&bih, sizeof(bih), 1, fp);
fwrite(pBuffer, stride * height, 1, fp);
fclose(fp);
return true;
}
int main() {
char names[16][256] = {0};
int cam_count = camera_enum_devices(names, 16);
std::cout << "检测到摄像头数量: " << cam_count << std::endl;
for (int i = 0; i < cam_count; ++i) {
std::cout << " 摄像头[" << i << "]: " << names << std::endl;
}
void* cam = camera_init();
if (!cam) {
std::cout << "摄像头初始化失败\n";
return -1;
}
int w = 0, h = 0, stride = 0;
// 连续采集3张图片
for (int i = 0; i < 3; ++i) {
unsigned char* data = camera_capture_buffer(cam, &w, &h, &stride);
if (data) {
char fname[32];
sprintf(fname, "capture_%d.bmp", i+1);
std::cout << "采集成功,宽:" << w << " 高:" << h << " 步长:" << stride << std::endl;
if (SaveBitmapToFile(data, w, h, stride, fname)) {
std::cout << "已保存为 " << fname << "\n";
} else {
std::cout << "保存文件失败\n";
}
delete[] data;
} else {
std::cout << "采集失败!\n";
}
}
camera_release(cam);
return 0;
}
```
## 常见问题
- **如何判断采集是否成功?**
- camera_capture_buffer 返回非 NULL 即为成功。
- **如何连续采集多张图片?**
- 只需初始化一次摄像头(camera_init),然后多次调用 camera_capture 或 camera_capture_buffer 即可,无需重复初始化和释放。
- **fopen 警告**:已在实现文件和示例顶部加 `#define _CRT_SECURE_NO_WARNINGS`,无需担心。
- **字符集问题**:建议保存所有源文件为 UTF-8 编码,避免中文乱码。
- **找不到 SampleGrabber/相关类型**:请确保 `capture_camera.h` 已包含所有相关声明。
## 依赖环境
- Windows 7/10/11
- Visual Studio 2013 及以上
- 需要安装 Windows SDK(DirectShow 组件)
拿了吱一声,反应好我会做成DLL版本 |
|