my goal is to create a unsigned char buffer filled with 0-255 grey scale color.
each cell in the buffer is 0-255 (no RGB).
i would like to exract from grey scale pic only one parameter (0-255 grey scale).
how to do so with CImg?
thanks,
jose.
You can compute the luminance of your input sRGB image, like this, in CImg:
CImg<unsigned char> luminance = RGB.get_RGBtoYCbCr().channel(0);
where RGB is the name of your RGB image.
Related
the figure outputted just displays the binary mask image, however I am trying to get just the foreground of the coloured image, with the background being black.
original = imread('originalImage.jpg');
binaryImage = imread('binaryImage.png');
mask = cat(3,binaryImage, binaryImage, binaryImage);
output = mask.*original;
figure,imshow(output);
the binary mask
The original image
The most likely issue is that binary is an image with values of 0 for background and 255 for foreground. Multiplying a color image with values in the range [0,255] by such a mask leads to overflow. Since the input images are uint8, overflow leads to values of 255. Thus, everywhere where the mask is white, you get white colors.
The solution is to convert the images to double:
output = double(mask)/255 .* double(original)/255;
or to truly binarize the mask image:
output = (mask>0) .* original;
I have a RGB image that I have processed and binarized and now I would like to return the original color only for the regions that now are white on the binarized image.
Is it possible to do so?
I've tried doing the following code, first I convert the data type from logical to double and then I try to return the original color, but it seems that doesn't works. The resulting image is a completely white image.
rz = double(rz);
rz(:,:,3)=I2(:,:,3);
rz(:,:,2)=I2(:,:,2);
rz(:,:,1)=I2(:,:,1);
rz is the binarized image while I2 is the original RGB image.
Is it possible to return the original color only for the regions that are white on the binarized image? What I'm doing wrong?
Assuming rz is logical NxMx1 image (i.e. you did not binarize differently in each dimensions)
Iout=I2;
Iout=bsxfun(#times,Iout,uint8(rz))
does the job. Basically you convert rz to double, and then multiply it with each color channel of Iout (using bsxfun). The resulting image will have the color [0,0,0] if the mask is zero in that pixel.
I want to change green color pixels to gold color in peppers.png image in Matlab.
How can I do this task? Thanks very much for your help
Introduction
Using the HSV colorspace gives a better intuition of detecting a certain color hue and manipulating it. For further information, read the following answer.
Solution
Given an image in hsv format, each color has a certain range which it can reside in. In the peppers image, the hue channel of green peppers is in the range [40/360,180/360] (more or less). Also, the color gold can be identified by a hue value of 0.125 and 'V' value of 0.8. Therefore, a good way to change green to gold in a certain picture will be as follows:
transform the image to hsv.
locate green colors by identifying hue value between the range [40/360,180/360].
changing their first channel to 0.125, and their second channel to 0.8.
transform back to rgb.
*comment: instead of fully changing the third channel of the green pixels to 0.8, it will be better to perform an averaging of 0.8 with the originally stored value, to get a more natural effect (see code below).
Code
%reads the image. converts it to hsv.
I = imread('peppers.png');
hsv = rgb2hsv(I);
%locate pixels with green color
GREEN_RANGE = [40,180]/360;
greenAreasMask = hsv(:,:,1)>GREEN_RANGE(1) & hsv(:,:,1) < GREEN_RANGE(2);
%change their hue value to 0.125
HUE_FOR_GOLD = 0.12;
V_FOR_GOLD = 0.8;
goldHsv1 = hsv(:,:,1);
goldHsv1(greenAreasMask)=HUE_FOR_GOLD;
goldHsv3 = hsv(:,:,3);
goldHsv3(greenAreasMask)=V_FOR_GOLD;
newHsv = hsv;
newHsv(:,:,1) = goldHsv1;
newHsv(:,:,3) = newHsv(:,:,3) + goldHsv3 / 2;
%transform back to RGB
res = hsv2rgb(newHsv);
Result
As you can see, the green pixels became more goldish.
There is a room for improvement, but I think that this would be a good start for you. To improve the result you can modify the green and gold HSV values, and use morphological operations on greenAreasMask.
I have 2 images. One is background image and other image has same background but with some foreground object. I want to extract foreground object from background. Simple subtraction operation in matlab will not suffice as it subtracts RGB value of background image from that of foreground image (as in below code).
im1 = imread('output/frame-1.jpg')
im2 = imread('output/frame-7.jpg')
%# subtract
deltaImage = im1 - im2;
imshow(deltaImage)
So if background color is white and foreground object is blue, then output (i.e. deltaImage) comes foreground object with orange color with black background. However the output I want is foreground object with blue color (i.e. original color) with black background. How can I get this ? I tried to do it using below code, but output image is incorrect.
im1 = imread('foreground.jpg')
im2 = imread('background.jpg')
[m n k]=size(im2);
deltaImage = zeros(m,n,3);
fprintf('%d %d %d.\n',m,n,k);
for l=1:k
for i=1:m-1
for j=1:n-1
if im1(i:j:l)~=im2(i:j:l)
deltaImage(i,j,l) = im1(i,j,l);
end
end
end
end
imshow(deltaImage)
Background IMAGE
Foreground Image
Output Image (Here I want color of man to be blue)
You can use deltaImage to create a mask (zeros and ones image) that multiplies the foreground. However, note that you will have artifacts associated with lossy image compression (.jpeg). These can be reduced, to some extent, if you use a threshold, like the average difference or a specific value you want. Try this:
im1 = double(imread('~/Downloads/foreground.jpg'));
im2 = double(imread('~/Downloads/background.jpg'));
compute the difference of the averages of the 3 channels
deltaImage = mean(im2,3) - mean(im1,3);
then use the product of the mean by a standard deviation (~3), or uncomment the line below to use a specific threshold, like 128
mask = deltaImage>3*mean(deltaImage(:));
% mask = deltaImage>128;
then assuming all original images are in 8-bit format produce a result also in 8-bit format:
result = uint8(cat(3, im1(:,:,1).*mask, im1(:,:,2).*mask, im1(:,:,3).*mask));
imshow(result)
And this is the result you should get:
Again the weird looking pixels around the main object are artifacts of lossy image compression (.jpeg), you should try working with lossless like .png formats.
I need to change the white skin face to dark skin face...
For example American white face to African face(i.e color tone)...
I pick the color value of the pixel by digital color meter it gives the RGB value[red=101,green=63 and blue=43] for dark skin and for white skin it gives the RGB value as [red=253,green=210 and blue=176]...
Then i am setting that value in my code it gives the false result...
Here is my code...
-(UIImage*)customBlackFilterOriginal
{
CGImageRef imgSource=self.duplicateImage.image.CGImage;
CFDataRef m_DataRef1 = CGDataProviderCopyData(CGImageGetDataProvider(imgSource));
UInt8 *dataOriginal=(UInt8 *)CFDataGetBytePtr(m_DataRef1);
double lengthSource=CFDataGetLength(m_DataRef1);
NSLog(#"length::%f",lengthSource);
int redPixel;
int greenPixel;
int bluePixel;
for(int index=0;index<lengthSource;index+=4)
{
dataOriginal[index]=dataOriginal[index];
dataOriginal[index+1]= 101;
dataOriginal[index+2]= 63;
dataOriginal[index+3]=43;
}
NSUInteger width =CGImageGetWidth(imgSource);
size_t height=CGImageGetHeight(imgSource);
size_t bitsPerComponent=CGImageGetBitsPerComponent(imgSource);
size_t bitsPerPixel=CGImageGetBitsPerPixel(imgSource);
size_t bytesPerRow=CGImageGetBytesPerRow(imgSource);
NSLog(#"the w:%u H:%lu",width,height);
CGColorSpaceRef colorspace=CGImageGetColorSpace(imgSource);
CGBitmapInfo bitmapInfo=CGImageGetBitmapInfo(imgSource);
CFDataRef newData=CFDataCreate(NULL,dataOriginal,lengthSource);
CGDataProviderRef provider=CGDataProviderCreateWithCFData(newData);
CGImageRef newImg=CGImageCreate(width,height,bitsPerComponent,bitsPerPixel,bytesPerRow,colorspace,bitmapInfo,provider,NULL,true,kCGRenderingIntentDefault);
return [UIImage imageWithCGImage:newImg];
}
please share any idea about the above color changing....
what mistake i did in the code?..
I am not an IPhone programmer so I can't test anything but some things are odd in your code:
Pixel size
When reading your data, you seem to assume you have a 32bits ARGB picture, did you validate it's the case?
CFDataGetBytePtr
According to the docs, it Returns a read-only pointer to the bytes of a CFData object., are you sure you're not looking for CFDataGetBytes which Copies the byte contents of a CFData object to an external buffer. In which case you'll have to allocate your buffer to contain width * height * bpp. Once you have this copy, you can manipulate it anyway you want to create the new picture.
Pixel Selection
According to your question, I seem to understand that you want to change skin color from White to Black. Your current code iterates over every pixel to change its color. You should evaluate the "distance" between the pixel color and what you're looking for, and if it's below a certain threshold process it. It might be easier to perform the operation in HSV than by dealing with RGB colors.