Is there a algorithm of solarisation? - algorithm

i'm searching a algorithm to produce a solarisation effect of a picture. Have someone a link or a algorithm? I#m interessted in other filters too, like sepia or cartoon. For sepia i found some code here. On the web i found not much infos about the implementation of those filters.
greetings

solarisation means that the response curve is not monotonic (instead of simply increasing in brightness, the "output" starts bright, gets dimmer, and then increases again, as the "input" gets brighter). the easiest way to implement it (for some value of easy) is as a special case of a more general process which transforms pixel values.
here's some python-ish pseudocode for the main routine:
def transform(image, f):
for pixel in image:
pixel = f(pixel)
if we choose pixels to be values between 0 and 1 (normalise whatever values you have, and if you have colours treat R, G and B the same) then you can modify gamma (change contrast) by using
transform(image, f(x): x^gamma)
for solarisation, you need a function that decreases then increases again. so something like 1-4x+4x^2:
transform(image, f(x): 1-4x+4x^2)
in case that's all a bit opaque, here are some numbers to make things clearer:
if the input image is 0 (black) then the output would be 1-4*0+4*0^2 = 1 (white)
if the input image is 0.5 (grey) then the output would be 1-4*0.5+4*0.5^2 = 1-2+1 = 0 (black)
if the input image is 1 (white) then the output would be 1-4*1+4*1^2 = 1 (white)
then you could take it further by adding some parameters to the curve (eg a + bx + cx^2) that the user can alter.
(actually, it can be more general - it can have multiple peaks or go black at bright points - there's an ansel adams image with a black sun, for example. the idea's the same, just use a higher order polynomial, or change the sign of the parameters above - a -ve c will make bright areas dark. and you can use splines rather than polynomials. basically, it's a mapping from input to output that goes "up and down" and within that there's a lot of flexibility...).

Related

MATLAB image processing technique

I have this 3D array in MATLAB (V: vertical, H: horizontal, t: time frame)
Figures below represent images obtained using imagesc function after slicing the array in terms of t axis
area in black represents damage area and other area is intact
each frame looks similar but has different amplitude
I am trying to visualize only defect area and get rid of intact area
I tried to use 'threshold' method to get rid of intact area as below
NewSet = zeros(450,450,200);
for kk = 1:200
frame = uwpi(:,:,kk);
STD = std(frame(:));
Mean = mean(frame(:));
for ii = 1:450
for jj =1:450
if frame(ii, jj) > 2*STD+Mean
NewSet(ii, jj, kk) = frame(ii, jj);
else
NewSet(ii, jj, kk) = NaN;
end
end
end
end
However, since each frame has different amplitude, result becomes
Is there any image processing method to get rid of intact area in this case?
Thanks in advance
You're thresholding based on mean and standard deviation, basically assuming your data is normally distributed and looking for outliers. But your model should try to distinguish values around zero (noise) vs higher values. Your data is not normally distributed, mean and standard deviation are not meaningful.
Look up Otsu thresholding (MATLAB IP toolbox has it). It's model does not perfectly match your data, but it might give reasonable results. Like most threshold estimation algorithms, it uses the image's histogram to determine the optimal threshold given some model.
Ideally you'd model the background peak in the histogram. You can find the mode, fit a Gaussian around it, then cut off at 2 sigma. Or you can use the "triangle method", which finds the point along the histogram that is furthest from the line between the upper end of the histogram and the top of the background peak. A little more complex to explain, but trivial to implement. We have this implemented in DIPimage (http://www.diplib.org), M-file code is visible so you can see how it works (look for the function threshold)
Additionally, I'd suggest to get rid of the loops over x and y. You can type frame(frame<threshold) = nan, and then copy the whole frame back into NewSet in one operation.
Do I clearly understand the question, ROI is the dark border and all it surrounds? If so I'd recommend process in 3D using some kind of region-growing technique like watershed or active snakes with markers by imregionalmin. The methods should provide segmentation result even if the border has small holes. Than just copy segmented object to a new 3D array via logic indexing.

Zero out pixels that aren't at a particular intensity of a single colour

I'm having a little bit of difficulty wrapping my head around the correct terminology to use in phrasing my question, so I'll just take a stab at it and perhaps I can get some help in clarifying it along the way toward a solution.
I want to detect some coloured lights in an image, so I need a way to:
a) determine the colour of pixels
b) determine how "intense" or "bright" they are
c) use the two values above as a threshold or criteria for whether or not to discard a given pixel
I figured brightness alone will probably not be a good way to do this, since there will be non-zero ambient light.
Thanks!
EDIT: So using MATLAB's colour thresholder, I was able to isolate the coloured lights by restricting the hue range in HSV space. Just trying to figure out a way to do this via the command line.
Well there are two separate steps. 1 is finding out what you want to isolate, and 2 is isolation
1)Seems like you got this figured out. But for the future you can use the "imtool" command. It is nearly the same as imshow, but it allows you to inspect pixel values(RGB, you would convert these to HSV using rgb2hsv), crop images, zoom, measure distances, etc. It can be really helpful.
imtool(my_im)
will open up the window, pretty simple.
2)Now that you have your values you want to isolate them. The term you are looking for is MASKING A misk is typically a binary matrix/vector with 1's (true) corresponding to areas of interest and 0's (false) elsewhere. Matlab calls these "logical" arrays. So lets just say you found your areas of interest were as follows
hue=0.2 to 0.3, saturation=don't care, brightness= greater than .5
you would create your mask by doing binary comparisons on the pixels. I will split this into three steps just so you can make sense of everything.
%% MASKING STEPS
hue_idx = 1; sat_idx =2 ; bright_idx = 3;
hue_mask = ((my_hsv_im(:,:,hue_idx ) > 0.2) & (my_hsv_im(:,:,hue_idx ) < 0.3));
%note we have no saturation mask, because it would be filled with ones
%since we dont care about the saturation values
brightness_mask = (my_hsv_im(:,:,bright_idx ) > 0.5);
total_mask = hue_mask & brightness_mask;
%% ALL THE REST
%now we mask your image, recall that 1's are ares of interest and 0's are
%nothing so just multiply your image by your mask
% the mask is a logical array size MxNx1, we need to convert it to the same
%type as our image in order to multiply them
mask_3d(:,:,hue_idx) = total_mask;
mask_3d(:,:,sat_idx) = total_mask;
mask_3d(:,:,bright_idx) = total_mask;
mask_3d = uint8(mask_3d); %this step is pretty important, if your image
%is a double use double(mask_3d) instead
masked_rgb_im = my_im .* mask_3d;
%does some plotting just for fun
figure(10);
subplot(2,3,1);imshow(my_im);title('original image');
subplot(2,3,2);imshow(hue_mask);title('hue mask');
subplot(2,3,3);imshow(brightness_mask);title('bright mask');
subplot(2,3,4);imshow(total_mask);title('total mask');
subplot(2,3,5:6);imshow(masked_rgb_im );title('masked image');

Pixel movement C++

This may or may not be a very stupid question so I do apologise, but I haven't come across this in any books or tutorials as yet. Also I guess it can apply to any language...
Assume you create a window of size: 640x480 and an object/shape inside it of size 32x32 and you're able to move the shape around the window with keyboard inputs.
Does it matter what Type (int, float...) you use to control the movement of the shape. Obviously you can not draw halfway through a pixel, but if you move the shape by 0.1f (for example with a glTranslation function) what happens as supposed to moving it by an int of 1... Does it move the rendered shape by 1/10 of a pixel or?
I hope I've explained that well enough not to be laughed at.
I only ask this because it can affect the precision of collision detection and other functions of a program or potential game.
glTranslate produces a translation by x y z . The current matrix (glMatrixMode) is multiplied by this translation matrix, with the product replacing the current matrix, as if glMultMatrix were called with the following matrix for its argument:
1 0 0 x 0 1 0 y 0 0 1 z 0 0 0 1
If the matrix mode is either GL_MODELVIEW or GL_PROJECTION, all objects drawn after a call to glTranslate are translated.
Use glPushMatrix and glPopMatrix to save and restore the untranslated coordinate system.
This meaning that glTranslate will give you a translation, to use with the current matrix, resulting in non decimal numbers. You can not use half a pixel. glTranslate receives either doubles or floats, so if you are supposed to move it 1 in x,y or z, just give the function a float 1 or double 1 as an argument.
http://www.opengl.org/sdk/docs/man2/xhtml/glTranslate.xml
The most important reason for using floats or doubles to represent positioning is the background calculation. If u keep calculating your position with ints not only do you have to probably use conversion steps to get back to ints. You will also lose data every x amount of steps
if you want to animate you sprite to have anything less than 1 pixel movement per update then YES you need to use floating point, otherwise you will get no movement. your drawing function would most likely round to the nearest integer so it's probably not relevant for that. however you can of course draw to sub pixel accuracy!

Matlab restoring an image to its original colors

I want to take a picture of something.
The colors in the picture are not the same as I see in my eyes.
So in order to fix this problem, I decided to place a red paper (with RGB: [255 0 0]) and then take a picture including this paper.
If I see that the RGB of the paper is changed (such as [243 15 7]),
I will change all the RGB in the picture by the next way:
R (red), it will be added by value 12.
G (green), it will be subtracted by value 15.
B (blue), it will be subtracted by value 7.
By this way, my paper will be changed to his correct RGB [255 0 0] and then I can be sure that all the rest picture's RGB was changed to its original color.
What do you think about this way?
What you are trying to do is called Color Management/Color Correction.
I have some remarks:
First, you must make sure that your monitor is calibrated. If it isn't calibrated, it makes no sense to do a visual check. If you have a standard consumer monitor, chances are that you cannot calibrate it at all.
Why do you assume that the RGB of the paper is [255,0,0]? It could be slightly greener or bluer. You should use a known target, like Macbeth ColorChecker
The offset transformation that you are using, will not work if amount of light is changed. Instead, it should be multiplicative to be invariant to illumination intensity. Check out the standard method of color correction, Color Correction Matrix.
You will need more than one known color. Three is the absolute minimum to calibrate the matrix.
You can try to use white paper instead of red. By doing this, you will have information about three colors, not only red. In the perfect case, RGB values for white paper will be equal, for example, you get (197,197,197). But if they are not equal, for example (190, 204, 203), you can change them for each pixel by multiplying on some number:
mean = (190 + 204 + 203) / 3
red_new = red * mean / 190
green_new = green * mean / 204
blue_new = blue * mean / 203
i read about an iterative process of colour correction that could perhaps be applied in your case:
Correction with Photoshop in 7 Easy Steps by Helen
Bradley,
nevertheless, confirm that it works as expected
good luck

Determine a color “how much of a single color is in the image”

I’m trying to calculate an average value of one color over the whole image in order to determine how color, saturation or intencity or eny other value describing this changes between frmaes of the video.
However i would like to get just one value that will describe whole frame (and sigle, chosen color in it). Calculating simple average value of color in frame gives me very small differences between video frames, just 2-3 on a 0..255 space.
Is there any other method to determine color of the image other than histogram which as i understand will give me more than one value describing single frame.
Which library are you using for image processing? If it's OpenCV (or Matlab) then the steps here will be quite easy. Otherwise you'd need to look around and experiment a bit.
Use a Mean Shift filter on RGB (or gray, whichever) to cluster the colors in the image - nearly similar colors are clustered together. This lessens the number of colors to deal with.
Change to gray-level and compute a frequency histogram with bins [0...255] of pixel values that are present in the image
The highest frequency - the median - will correspond to the bin (color) that is present the most. The frequency of each bin will give you the no. of pixels of the color that is present in the frame.
Take the median value as the single color to describe your frame - the color present in the largest amount in the frame.
The key point here is if the above steps are fast enough for realtime video. You'd have to try to find out I guess.
Worst case scenario, you could loop over all the pixels in the image and do a count. Not sure what you are using programming wise but I use Python with Numpy something similar to this. Where pb is a gtk pixbuf with my image in it.
def pull_color_out(self, pb, *args):
counter = 0
dat = pb.get_pixels_array().copy()
for y in range(0,pb.get_width()):
for x in range(0,pb.get_height()):
p = dat[x][y]
#counts pure red pixels
if p[1] = 255 and p[2] = 0 and p[3] = 0:
counter += 1
return counter
Other than that, I would normally use a histogram and get the data I need from that. Mainly, this will not be your fastest option, especially for a video, but if you have time or just a few frames then hack away :P

Resources