OpenCV VideoCapture Выходное изображение обрезано до верхней левой четверти - PullRequest
1 голос
/ 03 мая 2019

Я пытаюсь интегрировать камеру 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 Ответ

0 голосов
/ 06 мая 2019

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

...