Сохранение изображения в OpenCV - PullRequest
25 голосов
/ 12 мая 2009

Я новичок в OpenCV и пытаюсь сделать снимок, а затем сохранить его в файл. Ниже выложен код для вашей справки, ниже.

Файл jpg сохраняется, но он черный.

// Capture the Image from the webcam
CvCapture *pCapturedImage = cvCreateCameraCapture(0);

// Get the frame
IplImage *pSaveImg = cvQueryFrame(pCapturedImage);

// Save the frame into a file
cvSaveImage("test.jpg". ,pSaveImg); // A JPG FILE IS BEING SAVED
                                    // OF 6KB , BUT IT IS BLACK

Все функции выполнены успешно. Я пробовал приведенный выше код как в XP, так и в Vista - в результате получается черное изображение на обоих. Пожалуйста, дайте мне знать, что я пропускаю.

Ответы [ 15 ]

20 голосов
/ 04 декабря 2012

Если вы используете C ++, лучше всего использовать интерфейс C ++ :

using namespace cv;
// Capture the Image from the webcam
VideoCapture cap(0);

// Get the frame
Mat save_img; cap >> save_img;

if(save_img.empty())
{
  std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;
}
// Save the frame into a file
imwrite("test.jpg", save_img); // A JPG FILE IS BEING SAVED
5 голосов
/ 13 мая 2009

Иногда первый вызов cvQueryFrame () возвращает пустое изображение. Попробуйте:

IplImage *pSaveImg = cvQueryFrame(pCapturedImage);
pSaveImg = cvQueryFrame(pCapturedImage);

Если это не сработает, попробуйте выбрать устройство захвата автоматически:

CvCapture *pCapturedImage = cvCreateCameraCapture(-1);

Или вы можете попробовать выбрать другие устройства захвата, где n = 1,2,3 ...

CvCapture *pCapturedImage = cvCreateCameraCapture(n);

PS: Я также считаю, что существует недопонимание по поводу захваченного изображения, когда вы смотрите на имя вашей переменной. Переменная pCapturedImage не является изображением, это Capture. Вы всегда можете «прочитать» изображение из захвата.

5 голосов
/ 22 февраля 2011

По моему опыту, OpenCV пишет черное изображение, когда SaveImage получает матрицу с разрядностью, отличной от 8-битной. На самом деле, это как-то задокументировано:

Только 8-битный одноканальный или 3-канальный (с порядком каналов BGR) изображения могут сохранить с помощью этой функции. Если формат, глубина или порядок каналов разные, используйте cvCvtScale и cvCvtColor чтобы конвертировать его раньше сохранить или использовать универсальный cvSave для сохранить изображение в формате XML или YAML.

В вашем случае вы можете сначала выяснить, какой тип изображения захватывается, изменить свойства захвата (я думаю, CV_CAP_PROP_CONVERT_RGB может быть важным) или впоследствии преобразовать его вручную.

Это пример того, как преобразовать в 8-битное представление с OpenCV. cc вот исходная матрица типа CV_32FC1, cc8u - это ее уменьшенная версия, которая на самом деле написана SaveImage:

# I want to save cc here
cc8u = CreateMat(cc.rows, cc.cols, CV_8U)
ccmin,ccmax,minij,maxij = MinMaxLoc(cc)
ccscale, ccshift = 255.0/(ccmax-ccmin), -ccmin
CvtScale(cc, cc8u, ccscale, ccshift)
SaveImage("cc.png", cc8u)

(извините, это код Python, но его легко перевести на C / C ++)

3 голосов
/ 19 апреля 2010

Я знаю проблему! Вы просто ставите точку после "test.jpg"!

cvSaveImage ("test.jpg"., PSaveImg);

Я могу ошибаться, но я думаю, что это нехорошо!

3 голосов
/ 14 мая 2009

извините, если это слишком очевидно. Вы уверены, что веб-камера правильно видна и обнаружена OpenCV другими словами, вы получаете изображение, когда перенаправляете захваченный кадр в окно "highGui"? Например, вот так:

 frame = cvQueryFrame( capture );
 cvNamedWindow( "myWindow", CV_WINDOW_AUTOSIZE );
 cvShowImage( "myWindow", frame );
2 голосов
/ 05 мая 2013

У меня была похожая проблема с моей веб-камерой Microsoft. Я просмотрел набор инструментов для сбора изображений в Matlab и обнаружил, что максимальное поддерживаемое разрешение составляет 640 * 480.

Я просто изменил код в openCV и добавил

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288);

перед функцией cvQueryFrame, которая была следующим поддерживаемым разрешением и изменена, пропустила некоторые начальные кадры, прежде чем сохранить изображение и, наконец, заработало.

Я делюсь своим рабочим кодом

#include "cv.h" 
#include "highgui.h" 
#include <stdio.h> 



using namespace cv;
using namespace std;

int main() 
{
CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 352); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 288)


 // Get one frame
IplImage* frame;

for (int i = 0; i < 25; i++) 
{
frame = cvQueryFrame( capture );
}


printf( "Image captured \n" );  
//IplImage* RGB_frame = frame;
//cvCvtColor(frame,RGB_frame,CV_YCrCb2BGR);
//cvWaitKey(1000);
cvSaveImage("test.jpg" ,frame);
//cvSaveImage("cam.jpg" ,RGB_frame);

printf( "Image Saved \n" );

//cvWaitKey(10);

// Release the capture device housekeeping
cvReleaseCapture( &capture );
//cvDestroyWindow( "mywindow" );
return 0;
}

Мои предложения:

  1. Не захватывать кадр с максимальным разрешением
  2. Пропустить некоторые кадры для правильной инициализации камеры
1 голос
/ 20 июня 2011

Сэйнт Льюис прав. Когда вы активируете камеру с помощью cvCaptureFromCAM, автоматический баланс белого еще не отрегулирован (это медленный процесс), поэтому вы можете получить в основном белый или в основном черный (зависит от камеры и условий освещения) в первых кадрах. То же самое происходит, когда происходит внезапное изменение освещения сцены. Просто подождите некоторое время после открытия камеры, очистите буфер, и вы готовы к работе.

1 голос
/ 18 марта 2011

Извините, что поднял старый пост, но я хотел бы дать другой ответ всем, кто сталкивается с этой темой.

У меня была такая же проблема. Независимо от того, что я сделал, изображение выглядело абсолютно черным. Я попытался сделать несколько последовательных вызовов cvQueryFrame и заметил, что когда я сделал 5 или больше, я мог видеть изображение. Поэтому я начал удалять вызовы один за другим, чтобы увидеть, где был «переломный момент». В итоге я обнаружил, что изображение становится темнее и мрачнее, когда я удаляю каждый звонок. Выполнение всего одного звонка позволило получить изображение, которое было почти полностью черным, но если бы я посмотрел очень внимательно, я мог бы разобрать свое изображение.

Я попробовал 10 последовательных звонков, чтобы проверить свою теорию, и, конечно же, мне дали очень яркое изображение, учитывая, что я нахожусь в слабо освещенной комнате. Надеюсь, это была та же проблема, с которой вы столкнулись.

Я не очень разбираюсь в работе с изображениями, но похоже, что несколько последовательных вызовов cvQueryFrame увеличивают продолжительность экспозиции для камеры. Это определенно решает проблему, хотя это не кажется самым элегантным решением. Я собираюсь посмотреть, смогу ли я найти параметр, который увеличит экспозицию, или, возможно, какой-то другой параметр, который осветлит мои изображения.

Удачи!

1 голос
/ 19 августа 2010

У меня была такая же проблема в Windows Vista, я просто добавил этот код до cvQueryFrame:

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 720);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
1 голос
/ 07 июля 2009

Я предлагаю вам запустить проверку работоспособности OpenCV

Это серия небольших исполняемых файлов, расположенных в каталоге bin opencv.

Он проверит, исправна ли ваша камера

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...