poing
Posts: 1132
Joined: Thu Mar 08, 2012 3:32 pm

Fine Tuning RAW image color

Sun Oct 27, 2013 4:14 pm

The Problem:
The stock lens of the camera board has strong vignetting. To counter this for the normal (jpeg) output strong processing is used, with the disadvantage that the dynamic range is reduced. When mounting the board behind a DSLR lens this processing becomes a fault, as the (center of such a) lens has no vignetting. Using a RAW image taken directly from the sensor with the --raw option circumvents this disadvantage since no in-camera (or in-Pi) processing is done.

However, because an as yet unknown reason there's still significant *color* (not lightness) vignetting present in the RAW images. Besides that there seems to be a significant red hue in the shadows and possibly other problems as well. The goal of this thread is to find solutions so that the RAW output can be easily used, especially for non-stock lenses.

The images in this post were all taken with a Nikkor 50mm F/1.4D lens @ f/4. The sensor is mounted behind the lens like so (the screws and springs are there to fine tune the position of the board in order to make it exactly perpendicular to the lens axis):
mountedCamera.jpg
mountedCamera.jpg (48.63 KiB) Viewed 2709 times
The scene I chose is a house at exactly 100m from the camera. On the left you see the jpeg image, on the right the RAW image directly taken from the DNG (created with raspi_dng from AlanD: http://www.raspberrypi.org/phpBB3/viewt ... 25#p361647):
13658_asshotsmall.jpg
13658_asshotsmall.jpg (55.23 KiB) Viewed 2709 times
I also created a 'calibration' image taken with a diffuser over the lens. On the left the jpeg, on the right the image taken directly from RAW:
2699_jpegsmall.jpg
2699_jpegsmall.jpg (24.26 KiB) Viewed 2709 times
I then wrote the following tiny program in Python. It reads a pixel from the (jpeg from raw) calibration image, determines the color difference from middle gray and then alters the same pixel from the (jpeg from raw) real image with the opposite color shift. Running this program on the Pi will take a few minutes for a single image, no doubt it will be much quicker with the right programming technique.

Code: Select all

import Image

im1 = Image.open("2699dng.jpg") #Open the calibration image taken with a diffuser
pix1 = im1.load()
size = im1.size #Get the width and hight of the image for iterating over
im2 = Image.open("13658dng.jpg") #Open the real image to be calibrated
pix2 = im2.load()

for x in range (0,size[0]):
	for y in range (0,size[1]):
		p1=pix1[x,y] #Get the RGBA Value of the a pixel of the calibration image
		dr=p1[0]-127
		dg=p1[1]-127
		db=p1[2]-127

		p2=pix2[x,y] #Get the RGBA Value of the a pixel of the real image
		r=p2[0]-dr
		g=p2[1]-dg
		b=p2[2]-db
		pix2[x,y] = (r,g,b) # Set the calibrated RGBA Value of the real image (tuple)

im2.save("final.jpg")
Continued in a second post with the rest of the images due to the three-inline-attachment limitation...
Last edited by poing on Sun Oct 27, 2013 4:34 pm, edited 1 time in total.

poing
Posts: 1132
Joined: Thu Mar 08, 2012 3:32 pm

Re: Fine Tuning RAW image color

Sun Oct 27, 2013 4:34 pm

The resulting image looks like this after editing in Photoshop (heavy jpeg compression):
test2_editmedium.jpg
test2_editmedium.jpg (60.57 KiB) Viewed 2700 times
This is a lot better, yet not perfect. Compared to the original but now edited jpeg (original edited jpeg on the left, result from RAW and calibration on the right):
13658_editedjpegdng.jpg
13658_editedjpegdng.jpg (51.45 KiB) Viewed 2700 times
Next I took a shot with a Nikon DSLR (different day, different light!) to get a hang on where I stand as the Nikon image is the more superior color-wise (Nikon left, Pi right):
003_6775_test2.jpg
003_6775_test2.jpg (49.04 KiB) Viewed 2700 times
The above is not a very good comparison as the light is totally different, but it's obvious there's a problem with reds in the Pi image.

All in all, I think the above calibration looks promising although the real deal will be to get it (after significant improvement) done inside the DNG file so that a RAW converter can be used to enhance the image before converting to jpeg.

Hope this all makes sense and please input your expertise on the matter, on any level.

poing
Posts: 1132
Joined: Thu Mar 08, 2012 3:32 pm

Re: Fine Tuning RAW image color

Fri Nov 29, 2013 12:52 pm

I'm not very far with this yet due to lack of time but here's an updated script that works better (changed the calculation of the pixel values):

Code: Select all

import Image, ast

im1 = Image.open("13658cal.jpg") #Open the calibration image taken with a diffuser
pix1 = im1.load()
im2 = Image.open("13658org.jpg") #Open the real image to be calibrated
pix2 = im2.load()
size = im2.size #Get the width and hight of the image for iterating over
for x in range (0,size[0]):
	for y in range (0,size[1]):
		p1=pix1[x,y] #Get the RGBA Value of the a pixel of the calibration image
		rp1=float(p1[0])
		gp1=float(p1[1])
		bp1=float(p1[2])
		p2=pix2[x,y] #Get the RGBA Value of the a pixel of the real image
		if rp1>0:r=int(p2[0]/rp1*255)
		g=int(p2[1]/gp1*255)
		b=int(p2[2]/bp1*255)
		#print p2[0],value
		pix2[x,y] = (r,g,b) # Set the calibrated RGBA Value of the real image (tuple)
im2.save("testP3.jpg")

Return to “Camera board”