读取三路视频,之后给缩放显示窗口程序,合成。
#include "MvCameraControl.h" #include <stdio.h> #include <Windows.h> #include <opencv2\opencv.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\core\core.hpp> //#include "readtable.h" using namespace std; using namespace cv; //extern Mat ImageArr[IMAGENUMBERS]; //extern Mat pano_Image; #include "opencv2/core/core.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include <opencv2\opencv.hpp> #include <Windows.h> #include<time.h> using namespace std; using namespace cv; #define TABLENUMBERS 1 //表的总数目 #define IMAGENUMBERS 3 //相机总数目 #define IMAGEWIDTH 2592 //单张图像长 #define IMAGEHEIGHT 2048 //单张图像宽 //#define zoom_WindowWIDTH 1632 //#define zoom_WindowHEIGHT 408 #define zoom_WindowWIDTH 1296 #define zoom_WindowHEIGHT 1024 //#define pano_WindowWIDTH 1632 //1920 // 展示图像宽度 //#define pano_WindowHEIGHT 408 //1080 //展示图像高度、 #define pano_WindowWIDTH 1296 //1920 // 展示图像宽度 #define pano_WindowHEIGHT 1024 //1080 //展示图像高度 #define RESULTIMAGEWIDTH 2592*3 #define RESULTIMAGEHEIGHT 2048*3 static float region_tl[2]; // top left corner of selected region static float region_size[2]; // region width and height static Mat constractTable[TABLENUMBERS]; // TABLENUMBERS 1个映射表 static int regionFlag[IMAGENUMBERS][2] = { 0 }; // IMAGENUMBERS 12数组 每个代表一个坐标点 每个有坐标(x y) static Mat ImageArr[IMAGENUMBERS]; // 存图 IMAGENUMBERS 12张 //Mat resultImage(IMAGEHEIGHT * 2, IMAGEWIDTH * 6, CV_8UC3, Scalar(0, 0, 0)); //结果大图 6列 2行 static Mat pano_Image(pano_WindowHEIGHT, pano_WindowWIDTH, CV_8UC3, Scalar(0, 0, 0)); //结果大图 6列 2行 // 采样率 必须相除为整数 否则会有黑影 #define IMAGE_WRATE float(RESULTIMAGEWIDTH) / float(pano_WindowWIDTH) //横向采样率 表宽度/屏幕宽度 12 #define IMAGE_HRATE float(RESULTIMAGEHEIGHT) / float(pano_WindowHEIGHT) //纵向向采样率 表高度/屏幕高度 12 static float rate = 1; static int centrelWidth = (pano_WindowWIDTH / 2)*rate, centrelHeight = (pano_WindowHEIGHT / 2)*rate; static bool setFlag = 0; static int centrelX = 0, centrelY = 0; static Mat displayImage(zoom_WindowHEIGHT, zoom_WindowWIDTH, CV_8UC3, Scalar(0, 0, 0)); /*查表映射 输入 单张图对应在大图中的左上角起始点 ( startx,starty) */ static uchar *tempInt1; //预览大图访问指针 static int *tableTemp1;//映射表指针 static uchar *tempInt_zoom; //缩放图访问指针 static int thread1;//图id static uchar* tempH;//访问图指针 /* 功能:读取文件名 */ void readTxt(string file, Mat* tempMat); void read_picture(); void read_map(); void onMouse(int event, int x, int y, int flags, void*); void init_Mouse(); void seedimage(Mat resultImage); void seedimage_use(int temleftX, int temleftY, int centrelWidth, int centrelHeight, Mat &show); void zoom_image(int tl_x, int tl_y, int win_w, int win_h, Mat &show); void Int_all(); void Do_show(Mat &show); //Mat show(zoom_WindowHEIGHT, zoom_WindowWIDTH, CV_8UC3, Scalar(0, 0, 0)); void readTxt(string file, Mat* tempMat) { FileStorage fInput(file, FileStorage::READ); fInput["vocabulary"] >> *tempMat; } /* 功能:读取12路图像 */ void read_picture() { //char pathPic[200]; //for (int i = 1; i <= IMAGENUMBERS; i++) //12张图 //{ // sprintf_s(pathPic, "./image/%d.bmp", i); // cout << pathPic << endl; // ImageArr[i - 1] = imread(pathPic); // if (ImageArr[i - 1].empty()) // { // return; // } //} } // 读取映射表 void read_map() { //----------------------------1读取表文件 char tablePath[100]; for (int i = 0; i < TABLENUMBERS; i++) { sprintf_s(tablePath, "./table/table_t_%d.xml", i); cout << " 读取映射表第" << i + 1 << "映射表...." << endl; readTxt(tablePath, &constractTable[i]); //表存在constractTable } //cout << "type = " << constractTable[0].type() << endl; cout << constractTable[0].cols << "---" << constractTable[0].rows << endl; cout << " 读取映射表成功 !" << endl; } /************************************************** *name :on_MouseHandle() *function :鼠标回调函数 *说明 : *time :2018-05-14 ***************************************************/ void onMouse(int event, int x, int y, int flags, void*) { double value; int centrelWidth = 0; int centrelHeight = 0; int temp_tlx = 0; int temp_tly = 0; switch (event) { case CV_EVENT_MOUSEWHEEL: value = getMouseWheelDelta(flags); if (value > 0) //向前滑动 { rate -= 0.1; if (rate <= 0.1) rate = 0.1; } else if (value < 0) //向后滑动 { rate += 0.1; if (rate > IMAGE_WRATE) { //rate = IMAGE_WRATE-0.1; rate = IMAGE_WRATE; } if (rate > IMAGE_HRATE) { //rate = IMAGE_HRATE-0.1; rate = IMAGE_HRATE; } } centrelWidth = zoom_WindowWIDTH * rate; centrelHeight = zoom_WindowHEIGHT * rate; if (centrelHeight >= RESULTIMAGEHEIGHT) { centrelHeight = RESULTIMAGEHEIGHT - 1; } if (centrelWidth >= RESULTIMAGEWIDTH) { centrelWidth = RESULTIMAGEWIDTH - 1; } temp_tlx = region_tl[0] + region_size[0] / 2 - centrelWidth / 2; temp_tly = region_tl[1] + region_size[1] / 2 - centrelHeight / 2; if (temp_tlx < 0) temp_tlx = 0; if (temp_tlx + centrelWidth > RESULTIMAGEWIDTH) temp_tlx = RESULTIMAGEWIDTH - centrelWidth - 1; if (temp_tly < 0) temp_tly = 0; if (temp_tly + centrelHeight > RESULTIMAGEHEIGHT) temp_tly = RESULTIMAGEHEIGHT - centrelHeight - 1; region_tl[0] = temp_tlx; region_tl[1] = temp_tly; region_size[0] = centrelWidth; region_size[1] = centrelHeight; setFlag = 1; cout << region_tl[0] << " 映射大图中扣取图像左上角坐标 " << region_tl[1] << endl; cout << region_size[0] << " 映射大图中扣取图像大小 " << region_size[1] << endl; break; case CV_EVENT_LBUTTONUP: { centrelX = x; centrelY = y; cout << centrelX << " 预览大图中鼠标点击位置 " << centrelY << endl; int tl_x = int(float(x*IMAGE_WRATE) - region_size[0] / 2); int tl_y = int(float(y*IMAGE_HRATE) - region_size[1] / 2); cout << tl_x << " tl " << tl_y << endl; if (tl_x >= 0 && tl_x < RESULTIMAGEWIDTH - region_size[0]) //判断点击时左上角坐标是否越界 { region_tl[0] = tl_x; } if (tl_x < 0) { region_tl[0] = 0; cout << " 鼠标点击且越界时左上角坐标0 " << region_tl[0] << endl; } if (tl_x + region_size[0] > RESULTIMAGEWIDTH) { region_tl[0] = RESULTIMAGEWIDTH - region_size[0] - 1; cout << " 鼠标点击且越界时左上角坐标0 " << region_tl[0] << endl; } if (tl_y >= 0 && tl_y < RESULTIMAGEHEIGHT - region_size[1]) { region_tl[1] = tl_y; } if (tl_y < 0) { region_tl[1] = 0; cout << " 鼠标点击且越界时左上角坐标1 " << region_tl[1] << endl; } if (tl_y + region_size[1] > RESULTIMAGEHEIGHT) { region_tl[1] = RESULTIMAGEHEIGHT - region_size[1] - 1; cout << " 鼠标点击且越界时左上角坐标1 " << region_tl[1] << endl; } cout << region_tl[0] << " 映射大图中扣取图像左上角坐标 " << region_tl[1] << endl; cout << region_size[0] << " 映射大图中扣取图像大小 " << region_size[1] << endl; setFlag = 1; cout << "左键点击" << setFlag << endl; } break; case CV_EVENT_RBUTTONUP: break; default: break; } } /************************************************** *name :on_MouseHandle() *function :窗口鼠标操作初始化 *说明 : *time :2018-05-14 ***************************************************/ void init_Mouse() { cvNamedWindow("mouse", 0); cvSetMouseCallback("mouse", onMouse, 0); } /* 功能: 获取游览全局缩略图 鼠标点击缩略图,直接截取点击处周围区域框 输入: 显示图resultImage 输出: 显示图resultImage */ void seedimage(Mat resultImage) { cout << "生成中,请稍等。。。。。" << endl; int storeX = 0, storeY = 0, storeZ = 0; // 表格信息 X 第几个图片中的(Y,Z)坐标点 int tempY = 0, tempX = 0;//Y X方向上的偏移量 //------------ 展示图 for (int i = 0; i < pano_WindowHEIGHT; i++) { tempInt1 = resultImage.ptr<uchar>(i); //大图的像素位置 i行 tableTemp1 = constractTable[0].ptr<int>(int(i*IMAGE_HRATE));//表的像素位置i+4 行 每4行取样 // 1080高 /2448*2 映射表高 for (int j = 0; j < zoom_WindowWIDTH; j++) { // cout << "------" << i << " ----- " << j << endl; storeX = *tableTemp1++; // 图像ID storeY = *tableTemp1++;// 像素坐标X storeZ = *tableTemp1++;//像素坐标Y tableTemp1 += int((IMAGE_WRATE - 1) * 3);//向后移动 10个像素 每10个采样 // 映射表读取出 这个点是是从storeX这个编号对应的图像来的 thread1 = storeX; //------------从单个图像中对应着位置的像素数据值 if (thread1 >= 1 && thread1 <= IMAGENUMBERS) // 如果有个这个图像 { // 映射表中的坐标信息赋值 tempX = storeY; tempY = storeZ; if (tempX >= 0 && tempX<IMAGEWIDTH && tempY >= 0 && tempY<IMAGEHEIGHT) { // 找到(thread1 - 1)编号对应的这个图像 并将指针移到tempY这一行首地址 tempH = ImageArr[thread1 - 1].ptr<uchar>(tempY); //将这个指针在这行水平移动tempX 这个像素但是每个像素有三个数据值(彩色图 RGB), 所以真实位置乘3 tempH += tempX * 3; // 依次将指针内的数据拷贝出 *tempInt1++ = *tempH++; *tempInt1++ = *tempH++; *tempInt1++ = *tempH++; } else { *tempInt1++ = 0; *tempInt1++ = 0; *tempInt1++ = 0; } //向后移动 10个像素 每10个采样 } else { *tempInt1++ = 0; *tempInt1++ = 0; *tempInt1++ = 0; } } } } /* 功能: 原始像素采集 缩放展示 输入: leftX leftY 鼠标窗口坐标 centrelWidth 以鼠标坐标为中心 截取宽度/2 centrelHeight 以鼠标坐标为中心 截取高度/2 输出 */ void seedimage_use(int temleftX, int temleftY, int centrelWidth, int centrelHeight, Mat &show) { //----1 窗口转换成表上的坐标 缩放倍数 int leftX = int(float(temleftX) *float(RESULTIMAGEWIDTH) / float(pano_WindowWIDTH)); int leftY = int(float(temleftY)* float(RESULTIMAGEHEIGHT) / float(pano_WindowHEIGHT)); cout << "映射表中心点---------!" << leftX << "---" << leftY << endl; int centrelX = leftX;// 临时变量 方便计算 int centrelY = leftY; //----2 判断映射设表上越界的问题 // 放大图不能超出映射表尺寸 // 坐上角定点不能越界 if ((RESULTIMAGEWIDTH - 2 * centrelWidth)>(centrelX - centrelWidth) && (centrelX - centrelWidth) >= 0) { leftX = centrelX - centrelWidth; } else if ((centrelX - centrelWidth) < 0) { leftX = 0; } else if ((RESULTIMAGEWIDTH - 2 * centrelWidth) <= (centrelX - centrelWidth)) { leftX = RESULTIMAGEWIDTH - 2 * centrelWidth; } if ((RESULTIMAGEHEIGHT - 2 * centrelHeight) > (centrelY - centrelHeight) && (centrelY - centrelHeight) >= 0) { leftY = centrelY - centrelHeight; } else if ((centrelY - centrelHeight) < 0) { leftY = 0; } else if ((RESULTIMAGEHEIGHT - 2 * centrelHeight) <= (centrelY - centrelHeight)) { leftY = RESULTIMAGEHEIGHT - 2 * centrelHeight; } cout << "映射表左上角顶点---- !" << leftX << "---" << leftY << endl; int storeX = 0, storeY = 0, storeZ = 0; // 表格信息 X 第几个图片中的(Y,Z)坐标点 int tempY = 0, tempX = 0;//Y X方向上的偏移量 //------------ 展示图 cout << "扣出图像尺寸--------" << centrelWidth * 2 << "---" << centrelHeight * 2 << endl; //cout << "映射表总大小-------!" << RESULTIMAGEWIDTH << "---" << RESULTIMAGEHEIGHT << endl; for (int i = 0; i < centrelHeight * 2; i++) { tempInt_zoom = show.ptr<uchar>(i); //大图的像素位置 i行 0-1080 // ------------------采样使用 Y int distance_y = 0; //if (rate<2.4&&rate >= 2) { // 图像大于2倍,开始采样 // distance = (rate - 2) * 10; // //} //else if (rate>=2.4) { distance = (2.4 - 2) * 10; } if (distance_y <= 4) { distance_y = centrelHeight * 2 / 1080; } else { distance_y = 4; } tableTemp1 = constractTable[0].ptr<int>(leftY + i + distance_y);//表的像素 找到行+ distance tableTemp1 += 3 * leftX;//表的像素 找到列 // 1080高 /2448*2 映射表高 for (int j = 0; j < centrelWidth * 2; j++) { storeX = *tableTemp1++; // 图像ID storeY = *tableTemp1++;// 像素坐标X storeZ = *tableTemp1++;//像素坐标Y //if (rate >= 2) { // 图像大于2倍,开始采样 // int distance = (rate - 2) * 10/2.5; // tableTemp1 += distance*3; //} int distance_x = 0; if (distance_x <= 10) { distance_x = centrelWidth * 2 / 1920; } else { distance_x = 10; } tableTemp1 += distance_x * 3; // 映射表读取出 这个点是是从storeX这个编号对应的图像来的 thread1 = storeX; //------------从单个图像中对应着位置的像素数据值 if (thread1) // 如果有个这个图像 { //cout << i << "---" << j << "---" << 1 << endl; // 映射表中的坐标信息赋值 tempX = storeY; tempY = storeZ; // 找到(thread1 - 1)编号对应的这个图像 并将指针移到tempY这一行首地址 tempH = ImageArr[thread1 - 1].ptr<uchar>(tempY); //将这个指针在这行水平移动tempX 这个像素但是每个像素有三个数据值(彩色图 RGB), 所以真实位置乘3 tempH += tempX * 3; // 依次将指针内的数据拷贝出 *tempInt_zoom++ = *tempH++; *tempInt_zoom++ = *tempH++; *tempInt_zoom++ = *tempH++; //向后移动 10个像素 每10个采样 } else { //cout << i << "---" << j << "---" << 0 << endl; *tempInt_zoom++ = 0; *tempInt_zoom++ = 0; *tempInt_zoom++ = 0; } } } } /* 功能:间隔抽样像素采集 缩放展示 参数: int tl_x 映射表 采样图左上角顶点x int tl_y 映射表 采样图左上角顶点y int win_w, 映射表 采样图宽 int win_h, 映射表 采样图长 Mat &show 映射表 采样图保存地址 */ void zoom_image(int tl_x, int tl_y, int win_w, int win_h, Mat &show) { float distance_y = 0;//y方向采样间隔 float distance_x = 0;//x方向采样间隔 distance_x = float(win_w) / float(zoom_WindowWIDTH); distance_y = float(win_h) / float(zoom_WindowHEIGHT); for (int i = 0; i < zoom_WindowHEIGHT; i++) { for (int j = 0; j < zoom_WindowWIDTH; j++) { int tempX = 3 * int(tl_x + j * distance_x); int camId = int(constractTable[0].ptr<int>(tl_y + int(i * distance_y))[tempX]);//表的像素 找到行+ distance int cam_u = int(constractTable[0].ptr<int>(tl_y + int(i * distance_y))[tempX + 1]);//表的像素 找到行+ distance int cam_v = int(constractTable[0].ptr<int>(tl_y + int(i * distance_y))[tempX + 2]);//表的像素 找到行+ distance if (camId >= 1 && camId <= IMAGENUMBERS) // 如果有个这个图像 { if (cam_u >= 0 && cam_u<IMAGEWIDTH && cam_v >= 0 && cam_v<IMAGEHEIGHT) { show.ptr<uchar>(i)[3 * j] = ImageArr[camId - 1].ptr<uchar>(cam_v)[3 * cam_u]; show.ptr<uchar>(i)[3 * j + 1] = ImageArr[camId - 1].ptr<uchar>(cam_v)[3 * cam_u + 1]; show.ptr<uchar>(i)[3 * j + 2] = ImageArr[camId - 1].ptr<uchar>(cam_v)[3 * cam_u + 2]; } else { show.ptr<uchar>(i)[3 * j] = 0; show.ptr<uchar>(i)[3 * j + 1] = 0; show.ptr<uchar>(i)[3 * j + 2] = 0; } //向后移动 10个像素 每10个采样 } else { show.ptr<uchar>(i)[3 * j] = 0; show.ptr<uchar>(i)[3 * j + 1] = 0; show.ptr<uchar>(i)[3 * j + 2] = 0; } } } } /* 功能: 初始化 */ void Int_all() { //------------------------------0 初始化映射表中采样图左上坐标 和 采样图大小 region_tl[0] = 0; region_tl[1] = 0; region_size[0] = pano_WindowWIDTH; region_size[1] = pano_WindowHEIGHT; //-------------------------------1 读取图像 //read_picture(); //-------------------------------2 读取映射表 read_map(); //-------------------------------3 合并缩略图像 //seedimage(pano_Image); //-------------------------------4初始化鼠标回调函数 init_Mouse(); //------------------------------- 5 合并交互图像 cout << "开始合并图像!" << endl; } void Do_show(Mat &show) { if (setFlag == 1) // 有鼠标操作后执行 { zoom_image(region_tl[0], region_tl[1], region_size[0], region_size[1], show); cout << "缩放倍数---" << rate << endl; setFlag = 0; if (!show.empty()) { cvNamedWindow("result", 0); imshow("result", show); } cout << "-----------------------------------------------" << endl; } imshow("mouse", pano_Image); waitKey(30); } //设置图片格式 string imgType = "Bayer";//"RGB" "YUV" unsigned char usb_leftID[2] = { 't','2' };//t1 or t3 unsigned char usb_rightID[2] = { 't','3' };//t2 or t4 unsigned char usb_shortID[2] = { 't','4' }; char gige_leftID = '7'; char gige_rightID = '6'; bool usb_flag = true; void main() { //设置触发模式 1=触发模式 0=连续模式 int TriggerMode = 0; //设置触发源为软触发 unsigned int enMode = MV_TRIGGER_SOURCE_LINE0;//MV_TRIGGER_SOURCE_SOFTWARE; int L_DeviceIndex = -1; int R_DeviceIndex = -1; int S_DeviceIndex = -1; void* S_handle = NULL; void* L_handle = NULL; void* R_handle = NULL; //枚举子网内指定的传输协议对应的所有设备 unsigned int nTLayerType; if (usb_flag) { nTLayerType = MV_USB_DEVICE;//MV_GIGE_DEVICE; } else { nTLayerType = MV_GIGE_DEVICE; } MV_CC_DEVICE_INFO_LIST m_stDevList = { 0 }; int nRet = MV_CC_EnumDevices(nTLayerType, &m_stDevList); if (MV_OK != nRet) { printf("error: EnumDevices fail [%x]\n", nRet); return; } cout << m_stDevList.nDeviceNum << endl; //检查网内设备数量 if (m_stDevList.nDeviceNum < 3) { printf("no camera found!\n"); return; } //查找所有设备名 if (usb_flag) { for (int i = 0; i < m_stDevList.nDeviceNum; i++) { MV_CC_DEVICE_INFO tempInfo = *m_stDevList.pDeviceInfo[i]; unsigned char *name = tempInfo.SpecialInfo.stUsb3VInfo.chUserDefinedName; cout << "cam " << i << " name = "; for (int j = 0; j < 3; j++) { cout << name[j]; } cout << endl; if (name[0] == usb_leftID[0] && name[1] == usb_leftID[1]) { L_DeviceIndex = i; } else if (name[0] == usb_rightID[0] && name[1] == usb_rightID[1]) { R_DeviceIndex = i; } else if (name[0] == usb_shortID[0] && name[1] == usb_shortID[1]) { S_DeviceIndex = i; } } } else { for (int i = 0; i < m_stDevList.nDeviceNum; i++) { MV_CC_DEVICE_INFO tempInfo = *m_stDevList.pDeviceInfo[i]; unsigned char *name = tempInfo.SpecialInfo.stGigEInfo.chUserDefinedName; cout << "cam " << i << " name = "; for (int j = 0; j < 2; j++) { cout << name[j]; } cout << endl; if (name[0] == gige_leftID) { L_DeviceIndex = i; } else if (name[0] == gige_rightID) { R_DeviceIndex = i; } } } if (L_DeviceIndex == -1 || R_DeviceIndex == -1 || S_DeviceIndex == -1) { cout << "error: Left Camera or Right Camera is not found!" << endl; return; } //**************************初始化短焦相机*************************** MV_CC_DEVICE_INFO S_stDevInfo = { 0 }; memcpy(&S_stDevInfo, m_stDevList.pDeviceInfo[S_DeviceIndex], sizeof(MV_CC_DEVICE_INFO)); nRet = MV_CC_CreateHandle(&S_handle, &S_stDevInfo); if (MV_OK != nRet) { printf("error: Short Camera CreateHandle fail [%x]\n", nRet); return; } //连接设备 nRet = MV_CC_OpenDevice(S_handle);//, nAccessMode, nSwitchoverKey); if (MV_OK != nRet) { printf("error: Short Camera OpenDevice fail [%x]\n", nRet); return; } //设置插值方式 MV_CC_SetBayerCvtQuality(S_handle, 2); if (MV_OK != nRet) { printf("error: Set Camera Quality fail [%x]\n", nRet); return; } //设置为触发模式 nRet = MV_CC_SetEnumValue(S_handle, "TriggerMode", TriggerMode); if (nRet != MV_OK) { printf("set trigger mode failed.\n"); return; } //设置触发模式为软触发模式 if (TriggerMode == 1) { nRet = MV_CC_SetEnumValue(S_handle, "TriggerSource", enMode); if (nRet != MV_OK) { printf("set soft trigger mode failed.\n"); return; } } //开始采集图像 nRet = MV_CC_StartGrabbing(S_handle); if (MV_OK != nRet) { printf("error: Short Camera StartGrabbing fail [%x]\n", nRet); return; } //获取一帧数据的大小 MVCC_INTVALUE S_stIntvalue = { 0 }; nRet = MV_CC_GetIntValue(S_handle, "PayloadSize", &S_stIntvalue); if (nRet != MV_OK) { printf("Short Camera Get PayloadSize failed! nRet [%x]\n", nRet); return; } int S_BufSize = S_stIntvalue.nCurValue; //一帧数据大小 unsigned char* S_FrameBuf = NULL; S_FrameBuf = (unsigned char*)malloc(S_BufSize); MV_FRAME_OUT_INFO_EX S_stInfo; memset(&S_stInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX)); //**************************初始化左相机*************************** MV_CC_DEVICE_INFO L_stDevInfo = { 0 }; memcpy(&L_stDevInfo, m_stDevList.pDeviceInfo[L_DeviceIndex], sizeof(MV_CC_DEVICE_INFO)); nRet = MV_CC_CreateHandle(&L_handle, &L_stDevInfo); if (MV_OK != nRet) { printf("error: Left Camera CreateHandle fail [%x]\n", nRet); return; } //连接设备 nRet = MV_CC_OpenDevice(L_handle);//, nAccessMode, nSwitchoverKey); if (MV_OK != nRet) { printf("error: Left Camera OpenDevice fail [%x]\n", nRet); return; } //设置插值方式 MV_CC_SetBayerCvtQuality(L_handle, 2); if (MV_OK != nRet) { printf("error: Set Camera Quality fail [%x]\n", nRet); return; } //设置为触发模式 nRet = MV_CC_SetEnumValue(L_handle, "TriggerMode", TriggerMode); if (nRet != MV_OK) { printf("set trigger mode failed.\n"); return; } //设置触发模式为软触发模式 if (TriggerMode == 1) { nRet = MV_CC_SetEnumValue(L_handle, "TriggerSource", enMode); if (nRet != MV_OK) { printf("set soft trigger mode failed.\n"); return; } } //开始采集图像 nRet = MV_CC_StartGrabbing(L_handle); if (MV_OK != nRet) { printf("error: Left Camera StartGrabbing fail [%x]\n", nRet); return; } //获取一帧数据的大小 MVCC_INTVALUE L_stIntvalue = { 0 }; nRet = MV_CC_GetIntValue(L_handle, "PayloadSize", &L_stIntvalue); if (nRet != MV_OK) { printf("Left Camera Get PayloadSize failed! nRet [%x]\n", nRet); return; } int L_BufSize = L_stIntvalue.nCurValue; //一帧数据大小 unsigned char* L_FrameBuf = NULL; L_FrameBuf = (unsigned char*)malloc(L_BufSize); MV_FRAME_OUT_INFO_EX L_stInfo; memset(&L_stInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX)); //**************************初始化右相机*************************** MV_CC_DEVICE_INFO R_stDevInfo = { 0 }; memcpy(&R_stDevInfo, m_stDevList.pDeviceInfo[R_DeviceIndex], sizeof(MV_CC_DEVICE_INFO)); nRet = MV_CC_CreateHandle(&R_handle, &R_stDevInfo); if (MV_OK != nRet) { printf("error: Right Camera CreateHandle fail [%x]\n", nRet); return; } //连接设备 nRet = MV_CC_OpenDevice(R_handle);//, nAccessMode, nSwitchoverKey); if (MV_OK != nRet) { printf("error: Right Camera OpenDevice fail [%x]\n", nRet); return; } //设置插值方式 MV_CC_SetBayerCvtQuality(R_handle, 2); if (MV_OK != nRet) { printf("error: Set Camera Quality fail [%x]\n", nRet); return; } //设置为触发模式 nRet = MV_CC_SetEnumValue(R_handle, "TriggerMode", TriggerMode); if (nRet != MV_OK) { printf("set trigger mode failed.\n"); return; } //设置触发模式为软触发模式 if (TriggerMode == 1) { nRet = MV_CC_SetEnumValue(R_handle, "TriggerSource", enMode); if (nRet != MV_OK) { printf("set soft trigger mode failed.\n"); return; } } //开始采集图像 nRet = MV_CC_StartGrabbing(R_handle); if (MV_OK != nRet) { printf("error: Right Camera StartGrabbing fail [%x]\n", nRet); return; } //获取一帧数据的大小 MVCC_INTVALUE R_stIntvalue = { 0 }; nRet = MV_CC_GetIntValue(R_handle, "PayloadSize", &R_stIntvalue); if (nRet != MV_OK) { printf("Right Camera Get PayloadSize failed! nRet [%x]\n", nRet); return; } int R_BufSize = R_stIntvalue.nCurValue; //一帧数据大小 unsigned char* R_FrameBuf = NULL; R_FrameBuf = (unsigned char*)malloc(R_BufSize); MV_FRAME_OUT_INFO_EX R_stInfo; memset(&R_stInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX)); unsigned int TestFrameCount = 0; int getframes = 0; char filenamel[250]; char filenamer[250]; char filenames[250]; char filenamel640[250]; char filenamer640[250]; int64 t; int64 t_new, t_old; t_old = GetTickCount(); Int_all(); while (1) { /*int64 t = GetTickCount();*/ //if (TestFrameCount > 900999) //{ // break; //} //如果为触发模式,则需要先进行一次触发 if (TriggerMode == 1 && enMode == MV_TRIGGER_SOURCE_SOFTWARE) { MV_CC_SetCommandValue(L_handle, "TriggerSoftware");//如果没有得到触发信号,相机无法获取图像 MV_CC_SetCommandValue(R_handle, "TriggerSoftware"); MV_CC_SetCommandValue(S_handle, "TriggerSoftware"); } t = GetTickCount(); //获取左相机图像 int LRet = MV_CC_GetOneFrameTimeout(L_handle, L_FrameBuf, L_BufSize, &L_stInfo, 500); //t = GetTickCount() - t; int RRet = MV_CC_GetOneFrameTimeout(R_handle, R_FrameBuf, R_BufSize, &R_stInfo, 500); int SRet = MV_CC_GetOneFrameTimeout(S_handle, S_FrameBuf, S_BufSize, &S_stInfo, 500); if (LRet != MV_OK || RRet != MV_OK || SRet != MV_OK) { Sleep(10); continue; } else { cv::Mat L_Img, R_Img, S_Img; cv::Mat L_Img640, R_Img640, S_Img640; if (imgType == "RGB") { cv::Mat L_BufImg(L_stInfo.nHeight, L_stInfo.nWidth, CV_8UC3, (unsigned char*)L_FrameBuf); cv::Mat R_BufImg(R_stInfo.nHeight, R_stInfo.nWidth, CV_8UC3, (unsigned char*)R_FrameBuf); cv::Mat S_BufImg(S_stInfo.nHeight, S_stInfo.nWidth, CV_8UC3, (unsigned char*)R_FrameBuf); cv::cvtColor(S_BufImg, S_Img, CV_BGR2RGB); cv::cvtColor(L_BufImg, L_Img, CV_BGR2RGB); cv::cvtColor(R_BufImg, R_Img, CV_BGR2RGB); } else if (imgType == "Bayer") { cv::Mat L_BufImg(L_stInfo.nHeight, L_stInfo.nWidth, CV_8UC1, (unsigned char*)L_FrameBuf); cv::Mat R_BufImg(R_stInfo.nHeight, R_stInfo.nWidth, CV_8UC1, (unsigned char*)R_FrameBuf); cv::Mat S_BufImg(S_stInfo.nHeight, S_stInfo.nWidth, CV_8UC1, (unsigned char*)R_FrameBuf); cv::cvtColor(S_BufImg, S_Img, CV_BayerBG2RGB); cv::cvtColor(L_BufImg, L_Img, CV_BayerBG2RGB); cv::cvtColor(R_BufImg, R_Img, CV_BayerBG2RGB); } else if (imgType == "YUV") { cv::Mat L_BufImg(L_stInfo.nHeight, L_stInfo.nWidth, CV_8UC2, (unsigned char*)L_FrameBuf); cv::Mat R_BufImg(R_stInfo.nHeight, R_stInfo.nWidth, CV_8UC2, (unsigned char*)R_FrameBuf); cv::Mat S_BufImg(S_stInfo.nHeight, S_stInfo.nWidth, CV_8UC2, (unsigned char*)R_FrameBuf); cv::cvtColor(S_BufImg, S_Img, CV_YUV2BGR_UYVY); cv::cvtColor(L_BufImg, L_Img, CV_YUV2BGR_UYVY); cv::cvtColor(R_BufImg, R_Img, CV_YUV2BGR_UYVY); } cv::namedWindow("Left", 0); cv::namedWindow("Right", 0); cv::namedWindow("Short", 0); cv::imshow("Short", S_Img); cv::imshow("Left", L_Img); cv::imshow("Right", R_Img); //Int_all(); //read_picture(); //-------------------------------------- if (S_Img.empty()&& L_Img.empty()&& R_Img.empty()) { printf("---------------- Camera failed! -----------------"); } else { Mat S_Img_roi, S_Img_reroi; Rect rect(823, 600, 880, 634); S_Img_roi = S_Img(rect); resize(S_Img_roi, S_Img_reroi, Size(2592, 2048), 0, 0, INTER_LINEAR); ImageArr[0] = S_Img_reroi; ImageArr[1] = L_Img; ImageArr[2] = R_Img; seedimage(pano_Image); Mat show(zoom_WindowHEIGHT, zoom_WindowWIDTH, CV_8UC3, Scalar(0, 0, 0)); Do_show(show); } //-------------------------------------- //sprintf(filenamel, "left%d.jpg", getframes); //sprintf(filenamer, "right%d.jpg", getframes); //sprintf(filenames, "short%d.jpg", getframes); ////sprintf(filenamel640, "left640/left%d.jpg", getframes); ////sprintf(filenamer640, "right640/right%d.jpg", getframes); //imwrite(filenamel, L_Img); //imwrite(filenamer, R_Img); //imwrite(filenames, S_Img); ////resize(L_Img, L_Img640, Size(640, 480)); ////resize(R_Img, R_Img640, Size(640, 480)); ////imwrite(filenamel640, L_Img640); ////imwrite(filenamer640, R_Img640); //printf("以保存%d张", ++getframes); char key = cv::waitKey(1); if (key == 'q') { break; } if (key == 's') { sprintf(filenamel, "left/left%d.jpg", getframes); sprintf(filenamer, "right/right%d.jpg", getframes); sprintf(filenames, "short/short%d.jpg", getframes); //sprintf(filenamel640, "left640/left%d.jpg", getframes); //sprintf(filenamer640, "right640/right%d.jpg", getframes); imwrite(filenamel, L_Img); imwrite(filenamer, R_Img); imwrite(filenames, S_Img); //resize(L_Img, L_Img640, Size(640, 480)); //resize(R_Img, R_Img640, Size(640, 480)); //imwrite(filenamel640, L_Img640); //imwrite(filenamer640, R_Img640); printf("以保存%d张", getframes); getframes++; } TestFrameCount++; //printf("get %d frames\n", TestFrameCount); } t_new = GetTickCount(); int64 time = t_new - t_old; t_old = t_new; t = GetTickCount() - t; system("cls"); printf("get %d frames\n", TestFrameCount); /*t = GetTickCount() - t;*/ std::cout << "times = " << (double)time / cvGetTickFrequency() << std::endl; std::cout << "time = " << (double)t / cvGetTickFrequency() << std::endl; } /*********************停止左相机*************************/ //停止采集图像 nRet = MV_CC_StopGrabbing(L_handle); if (MV_OK != nRet) { printf("error: Left Camera StopGrabbing fail [%x]\n", nRet); return; } //关闭设备,释放资源 nRet = MV_CC_CloseDevice(L_handle); if (MV_OK != nRet) { printf("error: Left Camera CloseDevice fail [%x]\n", nRet); return; } //销毁句柄,释放资源 nRet = MV_CC_DestroyHandle(L_handle); if (MV_OK != nRet) { printf("error: Left Camera DestroyHandle fail [%x]\n", nRet); return; } /*********************停止右相机*************************/ //停止采集图像 nRet = MV_CC_StopGrabbing(R_handle); if (MV_OK != nRet) { printf("error: Right Camera StopGrabbing fail [%x]\n", nRet); return; } //关闭设备,释放资源 nRet = MV_CC_CloseDevice(R_handle); if (MV_OK != nRet) { printf("error: Right Camera CloseDevice fail [%x]\n", nRet); return; } //销毁句柄,释放资源 nRet = MV_CC_DestroyHandle(R_handle); if (MV_OK != nRet) { printf("error: Right Camera DestroyHandle fail [%x]\n", nRet); return; } /*********************停止短焦相机*************************/ //停止采集图像 nRet = MV_CC_StopGrabbing(S_handle); if (MV_OK != nRet) { printf("error: Short Camera StopGrabbing fail [%x]\n", nRet); return; } //关闭设备,释放资源 nRet = MV_CC_CloseDevice(S_handle); if (MV_OK != nRet) { printf("error: Short Camera CloseDevice fail [%x]\n", nRet); return; } //销毁句柄,释放资源 nRet = MV_CC_DestroyHandle(S_handle); if (MV_OK != nRet) { printf("error: Short Camera DestroyHandle fail [%x]\n", nRet); return; } }