6

Note that I am referring to the C++ library, raspicam (http://www.uco.es/investiga/grupos/ava/node/40), not the raspberry pi camera in general. Unfortunately, I don't have the reputation to make a "raspicam" tag.

It seems that camera images grabbed and retrieved from the raspberry pi camera are far darker than what they should be, but the brightness improves if I grab 3 images and only take the last one.

Images: https://i.sstatic.net/EB8vY.jpg

For each image in the album I changed tFrameCount to 1, 2, 3, and 4

Code: (main.cpp)

// to compile: g++ -o main main.cpp -lraspicam_cv -lraspicam `pkg-config --libs opencv`

#include <iostream>
#include <raspicam/raspicam_cv.h>
#include <exception>
#include <stdexcept>

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace std; 
using namespace cv;

Mat Raspi_Capture()
{
    raspicam::RaspiCam_Cv tCamera;

    cv::Mat tCapturedImage;

    int tFrameCount = 1;

    //Get an 8 bit single channel image (greyscale image)
    // this property needs to be set BEFORE the camera is opened
    tCamera.set(CV_CAP_PROP_FORMAT, CV_8UC1);

    if (!tCamera.open()) 
    {
        runtime_error tError("[Raspi_Capture] Camera failed to open");
        throw tError;
    }

    //edited code: I set every property that implements any kind of automatic adjustment to a manual value

    //these properties need to be set AFTER the camera is opened

    tCamera.set(CV_CAP_PROP_GAIN, 50); // values range from 0 to 100
    tCamera.set(CV_CAP_PROP_EXPOSURE, 50); //-1 is auto, values range from 0 to 100
    tCamera.set(CV_CAP_PROP_WHITE_BALANCE_RED_V, 50); //values range from 0 to 100, -1 auto whitebalance
    tCamera.set(CV_CAP_PROP_WHITE_BALANCE_BLUE_U, 50); //values range from 0 to 100,  -1 auto whitebalance


    tCamera.grab();
    tCamera.retrieve(tCapturedImage);


    tCamera.release();

    return tCapturedImage;
}

int main() 
{   
    Mat tImage;

    try
    {   
        tImage = Raspi_Capture();

        imwrite("raw_image.png", tImage);
    }

    catch(runtime_error& tError)
    {
        cerr << "Error: " << tError.what() << endl;
    }

    return 0;
}

Note: in a previous program I put imwrite on every iteration of the for loop, this made it so that I only needed to capture twice to get a properly bright image.

EDIT: my guess is that this is related to auto exposure or gain

My hardware: Raspberry pi ONE model B, I bought the camera around the same time I bought the raspberry pi, I'm not sure if the camera changed since the first generation.

My software: OS: Raspbian 2015-05-05

EDIT 2:

After posting this question I read that the raspberry pi camera uses automatic gain / exposure / white balance.

I have also read that it's not possible to turn this off in raspistill (I am not using raspistill).

There's a couple posts referring to "raspicam" that could not disable automatic exposure, but I am not sure if they are referring to this library or the hardware in general (using raspistill, for example). I am thankful for what the developer made with raspicam but this was not a good name for this library.

Raspicam provides these properties in raspicam_cv.h:

 /**Sets a property in the VideoCapture. 
 * 
 * 
 * Implemented properties:
 * CV_CAP_PROP_FRAME_WIDTH,CV_CAP_PROP_FRAME_HEIGHT,
 * CV_CAP_PROP_FORMAT: CV_8UC1 or CV_8UC3
 * CV_CAP_PROP_BRIGHTNESS: [0,100]
 * CV_CAP_PROP_CONTRAST: [0,100]
 * CV_CAP_PROP_SATURATION: [0,100]
 * CV_CAP_PROP_GAIN: (iso): [0,100]
 * CV_CAP_PROP_EXPOSURE: -1 auto. [1,100] shutter speed from 0 to 33ms
 * CV_CAP_PROP_WHITE_BALANCE_RED_V : [1,100] -1 auto whitebalance
 * CV_CAP_PROP_WHITE_BALANCE_BLUE_U : [1,100] -1 auto whitebalance
 *
 */

Can somebody confirm that they can disable automatic gain/exposure?

Even after setting all of these properties to non-automatic settings, I still notice that it takes multiple captures.

EDIT 3: Looking at the source code for raspicam, it looks like the source requires the camera to be opened before you set exposure / etc. settings on it, note that the image format settings need to be set BEFORE the camera is opened.

The images I got back from the camera are pretty strange right now but it seems to be consistent no matter how many frames I take.

I made a new image album and added the manual gain image to the end of it. I think it's just a matter of adjusting the parameters...

EDIT 4: After many attempts to attempt to get the white balance/gain/exposure settings correct, I gave up and bought a logitech C310 camera, it seems about as fast as the raspberry pi camera and I just capture directly through opencv, I will be using this from now on.

4
  • WRT the tag, "raspicam" might have been better than "camera-board" to start with, but since that is explicitly what the latter refers to, I've created a tag synonym from raspicam->camera-board to prevent future issues. Thanks for pointing this out.
    – goldilocks
    Commented Jul 12, 2015 at 14:56
  • Have you tried adding a delay (e.g. 1 second) between the .set() and the .grab() to see if that makes a difference?
    – goldilocks
    Commented Jul 12, 2015 at 14:58
  • I think this is an automatic gain/exposure issue, I'm going to verify this now, it makes sense because it takes a (dark) initial image and ramps up the gain over time, which explains why adding imwrites to the for loop made it take less iterations, because each iteration took more time to execute.
    – grayhound4
    Commented Jul 12, 2015 at 15:00
  • 1
    @goldilocks I just tried adding a delay of 1 second between set() and also between grab() and retrieve() just to try it, unfortunately there's no difference in the image
    – grayhound4
    Commented Jul 12, 2015 at 15:26

1 Answer 1

1

If you use auto-exposure and auto-gain (=ISO) then yes, the camera needs few frames to actually determine how to set these values. This is normal behavior - if you need correctly exposed frame you need to wait some time after camera initialization. I think both exposure time and ISO should be manually controllable via raspistill's command-line parameters and I also saw these settings in AVA's C++ raspicam library.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.