OpenCV VideoCapture 输出图像剪切到左上四分之一

OpenCV VideoCapture Output image cut to top left quarter

我正在尝试将 IDS uEye 摄像头与 OpenCV 集成,目前还算可以。 我面临的问题是,当我使用 IDS SDK 查看相机图像时,我得到的是完整图像。但是使用 OpenCV 的 VideoCapture,我只能得到图像的左上四分之一。 我只是将一个矩形的图像分成四分之一,以阐明完整图像应该是什么(整个矩形)以及我从视频捕捉中得到的(仅左上角四分之一)
(来源:kheper.net

我已经尝试通过 cap.set 调整图像宽度和高度,并且由于 VideoCapture 行是在设置 uEye 相机参数之后,我很确定这不是设置问题与相机有关,更多的是 VideoCapture 本身

char strCamFileName[256];
char* pcImageMemory;
int memId;
int nRet = 0;

SENSORINFO sInfo;
IplImage* img;
HIDS hCam = 0;                // index 0 means taking first camera available
RECT rc;
MSG msg;
Mat frame(MaxImageSizeY, MaxImageSizeX, CV_8UC1);

nRet = is_InitCamera(&hCam, hWndDisplay);
if (nRet != IS_SUCCESS)
{
    cout << endl << "Error Connecting to Camera" << endl;
    cout << "Closing program..." << endl;
    return 0;
}
else
{
    cout << endl << "Camera initialisation was successful!" << endl << endl;
}

// you can query information about the sensor type of the camera
nRet = is_GetSensorInfo(hCam, &sInfo);
if (nRet == IS_SUCCESS)
{
    cout << "Cameramodel: \t\t" << sInfo.strSensorName << endl;
    cout << "Maximum image width: \t" << sInfo.nMaxWidth << endl;
    cout << "Maximum image height: \t" << sInfo.nMaxHeight << endl << endl << endl;
}
MaxImageSizeX = sInfo.nMaxWidth;
MaxImageSizeY = sInfo.nMaxHeight;
DisplayWidth = MaxImageSizeX;
DisplayHeight = MaxImageSizeY;

int nColorMode = IS_COLORMODE_CBYCRY;
int nBitsPerPixel = 32;


// Get number of available formats and size of list
UINT count;
UINT bytesNeeded = sizeof(IMAGE_FORMAT_LIST);
nRet = is_ImageFormat(hCam, IMGFRMT_CMD_GET_NUM_ENTRIES, &count, sizeof(count));
bytesNeeded += (count - 1) * sizeof(IMAGE_FORMAT_INFO);
void* ptr = malloc(bytesNeeded);
// Create and fill list
IMAGE_FORMAT_LIST* pformatList = (IMAGE_FORMAT_LIST*)ptr;
pformatList->nSizeOfListEntry = sizeof(IMAGE_FORMAT_INFO);
pformatList->nNumListElements = count;
nRet = is_ImageFormat(hCam, IMGFRMT_CMD_GET_LIST, pformatList, bytesNeeded);
// Prepare for creating image buffers
char* pMem = NULL;
int memID = 0;
// Set each format and then capture an image
IMAGE_FORMAT_INFO formatInfo;

// Allocate image mem for current format, set format
nRet = is_AllocImageMem(hCam, MaxImageSizeX, MaxImageSizeY, nBitsPerPixel, &pMem, &memID);
nRet = is_SetImageMem(hCam, pMem, memID);
nRet = is_ImageFormat(hCam, IMGFRMT_CMD_SET_FORMAT, &formatInfo.nFormatID, sizeof(formatInfo.nFormatID));


// Sets the color mode to be used when image data are saved or displayed by the graphics card
is_SetColorMode(hCam, nColorMode);

// allocates an image memory for an image, activates it and sets the way in which the images will be displayed on the screen
int nMemoryId;
is_AllocImageMem(hCam, MaxImageSizeX, MaxImageSizeY, nBitsPerPixel, &pcImageMemory, &nMemoryId);
is_SetImageMem(hCam, pcImageMemory, nMemoryId);
is_SetDisplayMode(hCam, IS_SET_DM_DIB);
is_HotPixel(hCam, IS_HOTPIXEL_DISABLE_CORRECTION, NULL, NULL);

IS_RECT AAOI;       // IS_RECT type variable for Auto AOI parameters
AAOI.s32X = MaxImageSizeX / 3 | IS_AOI_IMAGE_POS_ABSOLUTE;
AAOI.s32Width = MaxImageSizeX / 3;
AAOI.s32Y = MaxImageSizeY / 3 | IS_AOI_IMAGE_POS_ABSOLUTE;
AAOI.s32Height = MaxImageSizeY / 3;

double enable = 1;
double disable = 0;
is_SetAutoParameter(hCam, IS_SET_AUTO_SPEED, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_GAIN, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_WHITEBALANCE, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_FRAMERATE, &disable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SHUTTER, &disable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SENSOR_GAIN, &disable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SENSOR_WHITEBALANCE, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SENSOR_SHUTTER, &disable, 0);
is_AOI(hCam, IS_AOI_AUTO_BRIGHTNESS_SET_AOI, &AAOI, sizeof(AAOI));
is_AOI(hCam, IS_AOI_AUTO_WHITEBALANCE_SET_AOI, &AAOI, sizeof(AAOI));

VideoCapture cap;             //--- INITIALIZE VIDEOCAPTURE
int deviceID = 0;             // 0 = open default camera
int apiID = cv::CAP_ANY;      // 0 = autodetect default API
if (cap.open(deviceID, apiID))
{
    cout << "cap opened" << endl;
}
else
{
    cout << "cap not opened" << endl;
}

cout << "Press 1 to capture image" << endl
     << "Press 2 to use (last) captured image" << endl;

cap.read(frame);

据我所知VideoCapture应该可以从相机获取整个图像吧? 老实说,我真的很困惑为什么 VideoCapture 削减了图像的 3/4,我将不胜感激任何帮助

好的,我发现问题了... 我再次在原始 post 中遗漏了太多代码(因为有很多与 USB 相关的不相关代码)所以我将在此处包括我遗漏的最重要的部分

double enable = 1;
double disable = 0;
is_SetAutoParameter(hCam, IS_SET_AUTO_SPEED, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_GAIN, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_WHITEBALANCE, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_FRAMERATE, &disable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SHUTTER, &disable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SENSOR_GAIN, &disable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SENSOR_WHITEBALANCE, &enable, 0);
is_SetAutoParameter(hCam, IS_SET_ENABLE_AUTO_SENSOR_SHUTTER, &disable, 0);
is_AOI(hCam, IS_AOI_AUTO_BRIGHTNESS_SET_AOI, &AAOI, sizeof(AAOI));
is_AOI(hCam, IS_AOI_AUTO_WHITEBALANCE_SET_AOI, &AAOI, sizeof(AAOI));

//// Acquires a single image from the camera
//is_FreezeVideo(hCam, IS_WAIT);
//// Output an image from an image memory in the specified window
//int nRenderMode = IS_RENDER_FIT_TO_WINDOW;
//is_RenderBitmap(hCam, nMemoryId, hWndDisplay, nRenderMode);

is_ExitCamera(hCam);        // exit camera so that OpenCV can access as camera parameters have been set

CalibSet CS;        // declaring variable 'CS' under the class 'CalibSet'
Mat livemap1, livemap2;
FileStorage tfs(inputCalibFile, FileStorage::READ);     // Read the settings
if (!tfs.isOpened())
{
    cout << "Could not open the calibration file: \"" << inputCalibFile << "\"" << endl;
    return -1;
}
tfs["camera_matrix"] >> CS.CamMat;
tfs["distortion_coefficients"] >> CS.DistCoeff;
tfs["image_width"] >> CS.image.width;
tfs["image_height"] >> CS.image.height;
tfs.release();                                         // close Settings file

所以。基本上 class CalibSet 所做的是它保存 .xml 文件的值,该文件用于在不失真校准后提取值。 更多信息请点击这里 但是阻止 cap.set 工作的问题可能是最后几行。 tfs["image_width"] >> CS.image.width;tfs["image_height"] >> CS.image.height; 将 "image_width" 和 "image_height" 中的值存储在 class CalibSet.[=20 中的相应变量中=]

你猜怎么着....xml 文件中的宽度和高度是 640x480... 我将 .xml 中的那部分修改为假定的 1280x1024,并且摄像机的实时馈送得到修复,我终于得到了完整图像,而不是之前得到的 1/4。