(4) 相机从hkw取图(2个) -- 直接缩放程序放大缩小

时间:2021-09-07 20:27:06

读取三路视频,之后给缩放显示窗口程序,合成。

 

#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;
 }

}