OpenCV VideoCapture Выходное изображение обрезано до верхней левой четверти

Я пытаюсь интегрировать камеру IDS uEye с OpenCV, и пока она работает. Проблема, с которой я сталкиваюсь, заключается в том, что когда я использую SDK IDS для просмотра изображения с камеры, я получаю полное изображение. Но с помощью OpenCV VideoCapture я получаю только верхнюю левую четверть изображения. Я просто поместил изображение прямоугольника, разделенного на четверти, чтобы уточнить, каким должно быть полное изображение (весь прямоугольник) и что я получаю из видеозахвата (только верхняя левая четверть) http://www.kheper.net/topics/civilization/four.gif

Я уже пытался настроить ширину и высоту изображения с помощью 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 изображения, и я был бы признателен за любую помощь

1 ответ

Решение

Хорошо, я обнаружил проблему... Опять же, я упустил слишком много кода в исходном посте (потому что есть много несоответствующего кода, связанного с 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

Так. В основном то, что класс CalibSet делает это содержит значения для .xml файл, который используется для извлечения значений после калибровки без искажения. Подробнее об этом здесь Поиск данных калибровки камеры Но проблема, которая помешала cap.set от работы были, вероятно, эти последние несколько строк.tfs["image_width"] >> CS.image.width; а также tfs["image_height"] >> CS.image.height; который взял значения в "image_width" и "image_height" и сохранил их в соответствующих переменных в классе CalibSet,

И угадайте, что... Ширина и высота в .xml файл был 640x480... Я изменил эту часть в .xml до предполагаемого 1280x1024, и прямая трансляция с камеры была исправлена, и я наконец получил полное изображение вместо 1/4, которое я получил раньше.

Другие вопросы по тегам