I'm trying to reconstruct RGB from RAW Bayer data from a Canon DSLR but am having no luck. I've taken a peek at the dcraw.c source, but its lack of comments makes it a bit tough to get through. Anyway, I have debayering working but I need to then take this debayered data and get something that looks correct. My current code does something like this, in order:
Demosaic/debayer
Apply white balance multipliers (I'm using the following ones: 1.0, 2.045, 1.350. These work perfectly in Adobe Camera Raw as 5500K, 0 Tint.)
Multiply the result by the inverse of the camera's color matrix
Multiply the result by an XYZ to sRGB matrix fromm Bruce Lindbloom's site (the D50 sRGB one)
Set white/black point, I am using an input levels control for this
Adjust gamma
Some of what I've read says to apply the white balance and black point correction before the debayer. I've tried, but it's still broken.
Do these steps look correct? I'm trying to determine if the problem is 1.) my sequence of operations, or 2.) the actual math being used.
The first step should be setting black and saturation point because you need to apply white balance looking after saturated pixels in order to avoid magenta highlights:
And before demosaicing, apply white balacing. See here (http://www.guillermoluijk.com/tutorial/dcraw/index_en.htm) how applying white balance before demosaicing introduce artifacts.
After the first step (debayer) you should have a proper RGB image with right colors. Remaining steps are just cosmetics. So I'm guessing there's something wrong at step one.
One problem could be the Bayer pattern you're using to generate RGB image is different from the CFA pattern of the camera. Match sensor alignment in your code to that of the camera!
Related
I am a new user on image processing via Matlab. My first aim is applying the article and comparing my results and authors' results.
The article can be found here: http://arxiv.org/ftp/arxiv/papers/1306/1306.0139.pdf
First problem, Image Quality: In Figure 7, masks are defined but I couldn't reach the mask data set, and I use the screenshot so image quality is low. In my view, it can effect the results. Is there any suggestions?
Second problem, Merging images: I want to apply mask 1 on the Lena. But I don't want to use paint =) On the other hand, is it possible merging the images and keeping the lena?
You need to create the mask array. The first step is probably to turn your captured image from Figure 7 into a black and white image:
Mask = im2bw(Figure7, 0.5);
Now the background (white) is all 1 and the black line (or text) is 0.
Let's make sure your image of Lena that you got from imread is actually grayscale:
LenaGray = rgb2gray(Lena);
Finally, apply your mask on Lena:
LenaAndMask = LenaGray.*Mask;
Of course, this last line won't work if Lena and Figure7 don't have the same size, but this should be an easy fix.
First of all, You have to know that this paper is published in archive. when papers published in archive it is always a good idea to know more about the author and/or the university that published the paper.
TRUST me on that: you do not need to waste your time on this paper.
I understand your demand: but it is not a good idea to do get the mask by doing print screen. The pixel values that can be achieved by using print screen may not be the same as the original values. The zoom may change the size. so you need to be sure that the sizes are the same.
you can do print screen. past the image.
crop the mask.
convert rgb to gray scale.
threshold the gray scale to get the binary.
if you saved the image as jpeg. distortions because of high frequency edges will change edge shape.
I want to make filters like shown here
these are my target filters but can you please guide me how to go for them
how i can make filters like these?
which algorithms i need to follow? and which step i need to take as beginner?
Which is the better and easiest way to get the values of RGB and shades of filters .
copy of image from link above by spektre:
the source image is the first after camera in the first line.
very hard to say from single non test-screen image.
the black and white filter
is easy just convert RGB to intensity i and then instead RGB write iii color. The simplest not precise conversion is
i=(R+G+B)/3
but better way is use of weights
i=w0*R+w1*G+w2*B
where w0+w1+w2=1 the values can be found by a little google search effort
the rest
some filters seem like over exponated colors or weighted colors like this:
r=w0*r; if (r>255) r=255;
g=w1*g; if (g>255) g=255;
b=w2*b; if (b>255) b=255;
write an app with 3 scrollbars for w0,w1,w2 in range <0-10> and redraw image with above formula. After little experimenting you should find w0,w1,w2 for most of the filters ... The rest can be mix of colors like this:
r=w00*r+w01*g+w02*b; if (r>255) r=255;
g=w10*r+w11*g+w12*b; if (g>255) g=255;
b=w20*r+w21*g+w22*b; if (b>255) b=255;
or:
i=(r+g+b)/3
r=w0*r+w3*i; if (r>255) r=255;
g=w1*g+w3*i; if (g>255) g=255;
b=w2*b+w3*i; if (b>255) b=255;
btw if you want the closest similarity you can:
find test colors in input image
like R shades, G shades , B shades , RG,RB,BG,RGB shades from 0-255. Then get colors from filtered image at the same position and draw depedency graphs for each shade draw R,G,B intensities.
One axis is input image color intensity and the other one is R,G,B intensity of filtered color. Then you should see which formula is used directly and can also compute the weights from it. This is how over-exponation works for Red color
if the lines are not lines but curves
then some kind of gamma correction is used so formulas use polynomial of higher order (power of 2,3,4...) mostly power of 2 suffice. In that case the weights can be also negative !!!
some filters could use different color spaces
for example transform RGB to HSV shift hue and convert back to RGB. That will shift colors a little.
I've already asked this question on https://dsp.stackexchange.com/ but didn't get any answer! hope to get any suggestion here:
I have a project in which I have to recognize 2 lines in different "position", the lines are orthogonal but can be projected on different surfaces. I'm using opencv.
The intersection can be anywhere on the frame. The lines are red (the images show just the gray scale).
UPDATE
-I'll be using a gray scale camera !!!!!!!!!
-the background and objects on which the lines will be projected can change
I'm not asking for code, but only for hints about how can I solve this? I tried houghlines function but it works only for straight surfaces.
thanks in advance !
This is not that difficult task as it include straight line. I have done similar kind of project.
First of all if your image is colored covert it to gray scale.
Then use a calibrated median filter to blur the image.
Now subtract the blurred image from the gray scale image.
After step 3 if you look at the image you will see that the on the places of lines the intensity
is higher than the other parts of image because these line are contrasted and when we apply median
filter the subtracted value is more than the rest of image.
to get a cleaner distinction you need to use create a binary image ie. only black and white with
a particular thresh hold.
6.Finally you got yu lines if their is noise you can use top hat filtering after step 4 and
gaussian filtering after step 5.
You can take help from this paper on crack detection
I think AMI's idea is good.
You can also think about using controled laser source. In that case you can get image pair one with laser turned on and one with turned off, then find difference.
It can be interesting for you: http://www.instructables.com/id/3-D-Laser-Scanner/
Here's the result of subtracting the output of a median filter (r=6):
You might be able to improve things a bit by adjusting the median filter radius, but these wavy, discontinuous lines are going to be difficult to detect reliably.
You really need better source images. Here are a few suggestions:
A colour camera would help enormously. Apply a high-pass filter to the red and green channels, and calculate the difference between the two. The red lines will stand out much better then.
Can you make the light source brighter?
Have you tried putting a red filter over the camera lens? Ideally you want one with a pass band that matches the light source's wavelength as closely as possible — if the light is coming from a laser, then a suitable dichroic filter should give good results. But even a sheet of red plastic would be better than nothing. (Have you got an old pair of red/blue 3D glasses sitting around somewhere?)
Perhaps subtracting the grayscale image from the red channel would help to highlight the red. I'd post this as a comment but cannot do so yet.
I'm looking for a generic algorithm to calculate a red/cian anaglyph starting from the original image and his b/w depth map (example: http://www.swell3d.com/2008/07/turn-2d-painting-into-3d-anagl.html)
That algorythm are used, for example, in Photoshop but I can't find a readable explanation to reproduce it.
Thanks
After some researches I found what I was looking for.
First, I've readed some Photoshop/Gimp tutorials that describes how to make anaglyphs from two inputs: an image and its grayscale depth map. The core of the process is the use of "Displace Tool" and the depth map as a displacement map.
One of the several youtube tutorials: http://www.youtube.com/watch?v=gfYMe_vYhu4
So, I took some documentation about Gimp's Displace Tool by looking at this http://docs.gimp.org/en/plug-in-displace.html and directly at the source code of the tool (the method is very similar to the one proposed by Asgeir).
This lets us to produce two stereo images from the input, by looking at the depth map. The red and cyan colors of every image are calculated by reading this page http://3dtv.at/Knowhow/AnaglyphComparison_en.aspx ("Optimized" matrices are the best ones).
Then, the sum of the two images in one will produce the final anaglyph. Thanks everybody.
There are two algorithms involved. The first uses the original image and the depth map to produce a left and a right image. The second combines these images into a red-cyan anaglyph.
There are a couple ways to accomplish the first part. One is to take the original image and texture map it onto a fine mesh that lies flat in the XY plane. Then you tweak the Z values of each vertex in the mesh according to the corresponding value in the depth map. You've basically created a textured bas relief. You then use a 3D rendering algorithm to render the image from two vantage points that are offset horizontally by a small amount (essentially from the vantage point of a person's left and right eyes as they would view the bas relief).
There is probably a way to directly shift the pixels left and right which is a good fast approximation to what I described above.
Once you have the left and right images, you pass one through a cyan filter and one through a red filter. If you have RGB sources, that's as simple as taking the red channel from one image and combing it with the green and blue channels from the other image.
Anaglyphs work best with muted colors. If you have strong primaries, it won't look as good. You can use an algorithm to reduce the color saturation of the original image before you begin.
From the description in the link you provided I would assume that it is something like
for each pixel in depthmap
x_offset = (depthmap[x][y] / 255.0f) * MAX_PIXEL_OFFSET * DIRECTION
output[x + x_offset][y] = color_buffer[x][y]
blend output with color_buffer
Where MAX_PIXEL_OFFSET is the maximum shift in pixels and DIRECTION is -1 for one color and 1 for the other. This is assuming that the depthbuffer is one byte per pixel, range [0..255] and that 0 in the depthbuffer represents maximum distance.
i'm working in a project to recognize a bit code from an image like this, where black rectangle represents 0 bit, and white (white space, not visible) 1 bit.
Somebody have any idea to process the image in order to extract this informations? My project is written in java, but any solution is accepted.
thanks all for support.
I'm not an expert in image processing, I try to apply Edge Detection using Canny Edge Detector Implementation, free java implementation find here. I used this complete image [http://img257.imageshack.us/img257/5323/colorimg.png], reduce it (scale factor = 0.4) to have fast processing and this is the result [http://img222.imageshack.us/img222/8255/colorimgout.png]. Now, how i can decode white rectangle with 0 bit value, and no rectangle with 1?
The image have 10 line X 16 columns. I don't use python, but i can try to convert it to Java.
Many thanks to support.
This is recognising good old OMR (optical mark recognition).
The solution varies depending on the quality and consistency of the data you get, so noise is important.
Using an image processing library will clearly help.
Simple case: No skew in the image and no stretch or shrinkage
Create a horizontal and vertical profile of the image. i.e. sum up values in all columns and all rows and store in arrays. for an image of MxN (width x height) you will have M cells in horizontal profile and N cells in vertical profile.
Use a thresholding to find out which cells are white (empty) and which are black. This assumes you will get at least a couple of entries in each row or column. So black cells will define a location of interest (where you will expect the marks).
Based on this, you can define in lozenges in the form and you get coordinates of lozenges (rectangles where you have marks) and then you just add up pixel values in each lozenge and based on the number, you can define if it has mark or not.
Case 2: Skew (slant in the image)
Use fourier (FFT) to find the slant value and then transform it.
Case 3: Stretch or shrink
Pretty much the same as 1 but noise is higher and reliability less.
Aliostad has made some good comments.
This is OMR and you will find it much easier to get good consistent results with a good image processing library. www.leptonica.com is a free open source 'C' library that would be a very good place to start. It could process the skew and thresholding tasks for you. Thresholding to B/W would be a good start.
Another option would be IEvolution - http://www.hi-components.com/nievolution.asp for .NET.
To be successful you will need some type of reference / registration marks to allow for skew and stretch especially if you are using document scanning or capturing from a camera image.
I am not familiar with Java, but in Python, you can use the imaging library to open the image. Then load the height and the widths, and segment the image into a grid accordingly, by Height/Rows and Width/Cols. Then, just look for black pixels in those regions, or whatever color PIL registers that black to be. This obviously relies on the grid like nature of the data.
Edit:
Doing Edge Detection may also be Fruitful. First apply an edge detection method like something from wikipedia. I have used the one found at archive.alwaysmovefast.com/basic-edge-detection-in-python.html. Then convert any grayscale value less than 180 (if you want the boxes darker just increase this value) into black and otherwise make it completely white. Then create bounding boxes, lines where the pixels are all white. If data isn't terribly skewed, then this should work pretty well, otherwise you may need to do more work. See here for the results: http://imm.io/2BLd
Edit2:
Denis, how large is your dataset and how large are the images? If you have thousands of these images, then it is not feasible to manually remove the borders (the red background and yellow bars). I think this is important to know before proceeding. Also, I think the prewitt edge detection may prove more useful in this case, since there appears to be less noise:
The previous method of segmenting may be applied, if you do preprocess to bin in the following manner, in which case you need only count the number of black or white pixels and threshold after some training samples.