How to fine tune the arducam mipi camera image quality manually?
Published by bin on
New Home › Forums › 1. Cameras Modules for Raspberry Pi › Arducam MIPI Camera Modules › How to fine tune the arducam mipi camera image quality manually?
- This topic has 10 replies, 2 voices, and was last updated 10 months ago by
bin.
- AuthorPosts
- December 6, 2019 at 1:08 am #13740
bin
KeymasterAt present, due to the image sensor now has no built-in ISP, how to get the ideal image quality is the problem we have to overcome. Arducam now release a serial of mipi cameras, due to not have the raspberrypi official local hardware ISP support, Arducam technical team release some software ways to fine tune the image quality. The target of this topic is to tell user to how to use Arducam mipi api to tune the image quality.
Now Arducam mipi camera’s API supports adjust the exposure time and gain compensation manually. The related API is int arducam_set_control(CAMERA_INSTANCE camera_instance, int ctrl_id, int value)
* @param camera_instance Type CAMERA_INSTANCE, Obtained from arducam_init_camera function.
* @param ctrl_id Control id.
* @param value Control value.
* @return error code , 0 success, !0 error.
* example:
@code
arducam_set_control(camera_instance, V4L2_CID_EXPOSURE, 3000);
@endcode
* */
About the control ID, user can run ./list_format to check all the ID your sensor support.
In this topic, I use the imx298 as an example.
For example, If I set the exposure time to 0x00FF
If I set the exposure time to 0x0F00
User can enabe and disable the auto white balance using the int arducam_software_auto_white_balance(CAMERA_INSTANCE camera_instance, int enable) API.
If set arducam_software_auto_white_balance(camera_instance, 0), the image will be green
If set arducam_software_auto_white_balance(camera_instance, 1), the image will be better
Sometimes, after we enable the auto white balance, we can’t get the better image quality we need, we can use void arducam_manual_set_awb_compensation(uint32_t r_gain, uint32_t b_gain) API to compensation the red channel gain and blue channel gain.
User can use arducamstill command to test.
run ./arducamstill -? to get the help
For example if I set rgain to 100 and bgain to 150
[email protected]:~/MIPI_Camera/RPI $ ./arducamstill -t 0 -rgain 100 -bgain 150For example if I set rgain to 150 and bgain to 50
[email protected]:~/MIPI_Camera/RPI $ ./arducamstill -t 0 -rgain 150 -bgain 50
What’s more , for some lens support motor focus, about the focus control, user can use arducam_set_control(camera_instance, V4L2_CID_FOCUS_ABSOLUTE, value) API.
For example, if I set the value to 10
arducam_set_control(camera_instance, V4L2_CID_FOCUS_ABSOLUTE, 10)
The image will be blurring
If set the value to 190
arducam_set_control(camera_instance, V4L2_CID_FOCUS_ABSOLUTE, 190)
The image will be better.
Now, we release opencvGui demo and Video presentation. Visiting https://www.arducam.com/downloads/video/Arducam_Fine_Tune_Method_for_MIPI_Cameras.mp4
- This topic was modified 1 year, 1 month ago by
Lee Jackson.
- This topic was modified 11 months, 1 week ago by
bin.
- This topic was modified 1 year, 1 month ago by
- December 17, 2019 at 4:35 am #14203
Agris Reppo
GuestHello!
I dont know why, but when I use mode 2 with this code, it takes green pictures sometimes. I have original mipicamera library. Can you help? I am beginner as you can see. I changed capture.c code to have almost good solution. Only problem is that mode 3 makes pictures about 10 mb, but mode 2 does it with 2,5mb. I dont see very big difference in resolutions. Also that program takes pictures of moving objects, about 5-10cm/s. Sometimes blur occurs. My code is below. Thank you!
#include “arducam_mipicamera.h”
#include <linux/v4l2-controls.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <time.h> ///////////////#define LOG(fmt, args…) fprintf(stderr, fmt “\n”, ##args)
#define FOCUS_VAL 310 //range(0-65535) /// FOOKUSE SEADISTAMINE 50cm = 300
/// 40cm = 310
#define SOFTWARE_AE_AWB
//IMAGE_ENCODING_JPEG
//IMAGE_ENCODING_BMP
//IMAGE_ENCODING_PNG
IMAGE_FORMAT fmt = {IMAGE_ENCODING_JPEG, 50};void save_image(CAMERA_INSTANCE camera_instance, const char *name) {
arducam_set_control(camera_instance, V4L2_CID_FOCUS_ABSOLUTE, 315); // fookus
arducam_set_control(camera_instance, V4L2_CID_EXPOSURE, 500); //valguse sättimine //500
//arducam_software_auto_exposure(camera_instance, 1);
arducam_software_auto_white_balance(camera_instance, 1);
usleep(1000 * 1000 * 1);
usleep(1000*10);
BUFFER *buffer = arducam_capture(camera_instance, &fmt, 12000);
if (!buffer) {
LOG(“capture timeout.”);
return;
}
FILE *file = fopen(name, “wb”);
fwrite(buffer->data, buffer->length, 1, file);
fclose(file);
arducam_release_buffer(buffer);
}int main(int argc, char **argv) {
CAMERA_INSTANCE camera_instance;
////int width = 2336, height = 1748; /// vali mode 2
//// int width = 4672, height = 3496; /// vali mode 3char file_name[100];
time_t rawtime;////////////// Thu Dec 5 15:54:56 2019.jpg
struct tm * timeinfo;////////////
time ( &rawtime );////////////////////
timeinfo = localtime ( &rawtime );//////////////////
//////
time_t timer; ////////////////06-12-2019 08.35.29
char buffer[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime(buffer, 26, “%d-%m-%Y %H.%M.%S”, tm_info);
puts(buffer);
////
LOG(“Open camera…”);
int res = arducam_init_camera(&camera_instance);
if (res) {
LOG(“init camera status = %d”, res);
return -1;
}int mode = 3;////3 highest // mode 2 compensation 55, 200
arducam_manual_set_awb_compensation(60,200); // 150, 255 arducam_manual_set_awb_compensation(r_gain_conpensation,b_gain_conpensation);LOG(“Setting the mode…”);
//res = arducam_set_resolution(camera_instance, &width, &height);
res= arducam_set_mode(camera_instance, mode);if (res) {
LOG(“set resolution status = %d”, res);
return -1;
} else {
LOG(“Current mode is %d”, mode);
}if(fmt.encoding == IMAGE_ENCODING_JPEG){
// sprintf(file_name, “/home/pi/Desktop/Pildid/capture %s.jpg”, asctime (timeinfo));///////////
//sprintf(file_name, “/home/pi/Public/Avalik/RaspberryPi/capture %s.jpg”, asctime (timeinfo));///////////
sprintf(file_name, “/home/pi/Public/Avalik/RaspberryPi/capture %s.jpg”, buffer);
}LOG(“Capture image %s…”, file_name);
save_image(camera_instance, file_name);LOG(“Close camera…”);
res = arducam_close_camera(camera_instance);
if (res) {
LOG(“close camera status = %d”, res);
}
return 0;
} - December 17, 2019 at 10:21 pm #14262
Agris Reppo
GuestI have tried it without success. Its pretty random I think, few pictures okay, then few pictures green
. Frist picture green, five sec later, without green. I dont know, but with higher resolution that problem never occurs.
- December 19, 2019 at 10:47 pm #14324
Agris Reppo
GuestHello!
That really works! Thanks, you are genius. I dont know why I didnot notice that line of code. I thought something with white balance. It worked (usleep (1000 * 1000 * 3))
- December 24, 2019 at 4:47 am #14380
gorski
Guest<p style=”text-align: left;”>hey,</p>
thanks for the support!i was curious what would be the recommended procedure to get 2 or more differently exposed images as fast as possible from the raspberry and ar1820. preferably raw without further image processing. would it be possible for you to implement some sort of auto exposure bracketing with the sensor or will the hdr mode be available? why is not possible to change exposure time via api in capture_raw program?
thanks again for your work.
regards,
gorski
- March 12, 2020 at 2:33 am #21274
andreavaresio
ParticipantI have an issue in controlling manually the AR1820 sensor. I cannot
change the exposure, gain, Red balance and Blue balance.I attached a modified version of your source code (capture.c) that
parses from the command line the exposure,gain,rbal and bbal values,
disables any automatic control and set them before capturing.usage: capture exposure gain rbal bbal
Trying to setup 1 or 65000 as exposure provide the same output . It seems the setting is not applied. 8I tried also with other values)
./capture 1 16 64 64
./capture 65000 16 64 64
Here the code
#include “arducam_mipicamera.h”
#include <linux/v4l2-controls.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#define LOG(fmt, args…) fprintf(stderr, fmt “\n”, ##args)//IMAGE_ENCODING_JPEG
//IMAGE_ENCODING_BMP
//IMAGE_ENCODING_PNG
IMAGE_FORMAT fmt = {IMAGE_ENCODING_JPEG, 100};
void save_image(CAMERA_INSTANCE camera_instance, const char *name) {// The actual width and height of the IMAGE_ENCODING_RAW_BAYER format and the IMAGE_ENCODING_I420 format are aligned,
// width 32 bytes aligned, and height 16 byte aligned.
usleep(1000*10);
BUFFER *buffer = arducam_capture(camera_instance, &fmt, 12000);
if (!buffer) {
LOG(“capture timeout.”);
return;
}
FILE *file = fopen(name, “wb”);
fwrite(buffer->data, buffer->length, 1, file);
fclose(file);
arducam_release_buffer(buffer);
}int main(int argc, char **argv) {
if (argc!=5)
{
LOG(“usage capture exposure gain rgain bgain”);
exit(1);
}CAMERA_INSTANCE camera_instance;
int width = 0, height = 0;
char file_name[100];LOG(“Open camera…”);
int res = arducam_init_camera(&camera_instance);
if (res) {
LOG(“init camera status = %d”, res);
return -1;
}struct format support_fmt;
int index = 0;
char fourcc[5];
fourcc[4] = ‘\0’;
while (!arducam_get_support_formats(camera_instance, &support_fmt, index++)) {
strncpy(fourcc, (char *)&support_fmt.pixelformat, 4);
LOG(“mode: %d, width: %d, height: %d, pixelformat: %s, desc: %s”,
support_fmt.mode, support_fmt.width, support_fmt.height, fourcc,
support_fmt.description);
}
index = 0;
struct camera_ctrl support_cam_ctrl;
while (!arducam_get_support_controls(camera_instance, &support_cam_ctrl, index++)) {
int value = 0;
if (arducam_get_control(camera_instance, support_cam_ctrl.id, &value)) {
LOG(“Get ctrl %s fail.”, support_cam_ctrl.desc);
}
LOG(“index: %d, CID: 0x%08X, desc: %s, min: %d, max: %d, default: %d, current: %d”,
index – 1, support_cam_ctrl.id, support_cam_ctrl.desc, support_cam_ctrl.min_value,
support_cam_ctrl.max_value, support_cam_ctrl.default_value, value);
}
int mode = 4;
int exposure = atoi(argv[1]);
int gain = atoi(argv[2]);
int rbal = atoi(argv[3]);
int bbal= atoi(argv[4]);LOG(“Setting the mode…”);
// res = arducam_set_resolution(camera_instance, &width, &height);
printf(“choose the mode %d\r\n”, mode );
res= arducam_set_mode(camera_instance, mode);
if (res) {
LOG(“set resolution status = %d”, res);
return -1;
} else {
LOG(“Current mode is %d”, mode);
LOG(“Notice:You can use the list_format sample program to see the resolution and control supported by the camera.”);
}if (arducam_reset_control(camera_instance, V4L2_CID_FOCUS_ABSOLUTE)) {
LOG(“Failed to set focus, the camera may not support this control.”);
}if (arducam_software_auto_exposure(camera_instance, 0)) {
LOG(“ailed to switch off auto exposure.”);
}if (arducam_software_auto_white_balance(camera_instance, 0)) {
LOG(“ailed to switch off auto WB.”);
}printf(“setting exposure %d\n”, exposure);
if (arducam_set_control(camera_instance, V4L2_CID_EXPOSURE, exposure)) {
LOG(“Failed to set exposure, the camera may not support this control.”);
}printf(“setting gain %d\n”, gain);
if (arducam_set_control(camera_instance, V4L2_CID_GAIN, gain)) {
LOG(“Failed to set gain, the camera may not support this control.”);
}printf(“setting r/b bal %d %d\n”, rbal, bbal);
arducam_manual_set_awb_compensation(rbal, bbal);if(fmt.encoding == IMAGE_ENCODING_JPEG){
sprintf(file_name, “mode%d.jpg”, mode);
}
if(fmt.encoding == IMAGE_ENCODING_BMP){
sprintf(file_name, “mode%d.bmp”, mode);
}
if(fmt.encoding == IMAGE_ENCODING_PNG){
sprintf(file_name, “mode%d.png”, mode);
}
LOG(“Capture image %s…”, file_name);
save_image(camera_instance, file_name);LOG(“Close camera…”);
res = arducam_close_camera(camera_instance);
if (res) {
LOG(“close camera status = %d”, res);
}
return 0;
} - March 23, 2020 at 7:33 am #21467
bin
KeymasterHi,
Sorry for my later reply due to my ill. We have release arducamstill demo and it support getting image in different encode format.Please try to use arducamstill demo, you can get the user guide here: https://github.com/ArduCAM/MIPI_Camera/tree/master/RPI
- AuthorPosts
- You must be logged in to reply to this topic.