Подтвердить что ты не робот

Сохранение изображения в OpenCV

Я новичок в 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 - результат - это черное изображение на обоих. Пожалуйста, дайте мне знать, чего я упускаю.

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

CvCapture *pCapturedImage = cvCreateCameraCapture(-1);

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

CvCapture *pCapturedImage = cvCreateCameraCapture(n);

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

Ответ 3

По моему опыту 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/С++)

Ответ 4

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

 frame = cvQueryFrame( capture );
 cvNamedWindow( "myWindow", CV_WINDOW_AUTOSIZE );
 cvShowImage( "myWindow", frame );

Ответ 5

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

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

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

Ответ 6

У меня была аналогичная проблема с моей веб-камерой 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;
}

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

  • Не снимайте рамку с максимальным разрешением
  • Пропустить некоторые кадры для правильной инициализации камеры

Ответ 7

Я использую следующий код для захвата изображений:

CvCapture* capture = cvCaptureFromCAM( CV_CAP_ANY );
if(!capture) error((char*)"No Capture");
IplImage *img=cvQueryFrame(capture);

Я знаю, что это работает наверняка

Ответ 8

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

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

Он будет проверять, нормально ли ваша камера

Ответ 9

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

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 720);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);

Ответ 10

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

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

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

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

Удачи!

Ответ 11

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

Ответ 12

Из моих опытов первые несколько кадров, которые записываются при использовании:

frame = cvQueryFrame( capture );

Пребывание будет пустым. Вы можете подождать короткое время (около 3 секунд), а затем попытаться захватить изображение.

Ответ 13

Я думаю, просто камера не инициализируется в первом кадре. Попробуйте сохранить изображение после 10 кадров.

Ответ 14

В OSX сохранение видеокадров и неподвижных изображений работало только для меня, когда я дал полный путь к cvSaveImage:

cvSaveImage("/Users/nicc/image.jpg",img);

Ответ 15

надеюсь, что это сохранит изображения из вашей веб-камеры

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
   VideoCapture cap(0);

   Mat save_img;

   cap >> save_img;

   char Esc = 0;

   while (Esc != 27 && cap.isOpened()) {        
    bool Frame = cap.read(save_img);        
    if (!Frame || save_img.empty()) {       
        cout << "error: frame not read from webcam\n";      
        break;                                              
    }
    namedWindow("save_img", CV_WINDOW_NORMAL);  
    imshow("imgOriginal", save_img);            
    Esc = waitKey(1);
}
imwrite("test.jpg",save_img); 
}