I am trying to implement rgb2lab() function in opencv.Here is my input and output image(the following links):
Is this comparable to the output of Matlab function rgb2lab().If not,please give the output obtained by rgb2lab function in Matlab for the input image.
You can convert an RGB image to Lab in Matlab as:
img = imread('path_to_image');
% Matlab 2015
%lab = rgb2lab(img);
% Matlab 2013
cform = makecform('srgb2lab');
lab = applycform(img,cform);
and in OpenCV as:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
Mat3b img = imread("path_to_image");
Mat3b lab;
cvtColor(img, lab, COLOR_BGR2Lab);
// NOTE: pixel values are the same as Matlab now.
// However, since OpenCV stores RGB values as BGR,
// to VISUALIZE the same image as Matlab you
// need to swap R and B channels.
// For visualization, whatever colorspace the image is in,
// the image is always considered as an BGR image.
Mat3b visuallySameAsMatlab;
cvtColor(lab, visuallySameAsMatlab, COLOR_BGR2RGB);
return 0;
}
NOTE: the pixel values are the same as Matlab after the call to cvtColor(img, lab, COLOR_BGR2Lab);. However, for visualization purposes, you need to swap B and R channels, as OpenCV internally stores BGR images as RGB.
When you visualize an image, in whatever color space, you are considering the pixel value as RGB (or BGR in OpenCV).
Related
i'm trying to make histogram equalization code for normalized image without builtin function in MATLAB like 'histeq'
I have normalized gray image that has values between [0,1]
input_img = mat2gray(img);
and I have found an example code wihout histeq function
for i=1:size(GIm,1)
for j=1:size(GIm,2)
value=GIm(i,j);
freq(value+1)=freq(value+1)+1;
probf(value+1)=freq(value+1)/numofpixels;
end
end
sum=0;
no_bins=255;
%The cumulative distribution probability is calculated.
for i=1:size(probf)
sum=sum+freq(i);
cum(i)=sum;
probc(i)=cum(i)/numofpixels;
output(i)=round(probc(i)*no_bins);
end
for i=1:size(GIm,1)
for j=1:size(GIm,2)
HIm(i,j)=output(GIm(i,j)+1);
end
end
figure,imshow(HIm);
title('Histogram equalization');
but this code is applied to an image that has a grayscale of [0,255]
how should I apply this code to my grayscale normalized image?
my image size 450x450
Use the code you have to compute a 256-bin histogram by scaling your image to fit it:
input_img_255 = round(input_img * 255);
and then use input_img_255 with the code you have. round should be good enough to use the rounded double values as indices as in your code. If you want to be more exact you can use:
input_img_255 = uint8(round(input_img * 255));
so that the values are integers.
I have this problem in image processing and I couldn't find an algorithm to perform well under this condition.It's so simple to understand but I don't know how to implement it in OpenCV or in Matlab, so any algorithm or function in one of them (MATLAB or opencv) is helpful.
1 . lets suppose that an image and background of scene is like the below
2 . We apply an edge detector to image and my current image will be like the below picture.
now my Problem is that how we can find the biggest contour or area like the below in edge image?
If you want original picture the original picture is
and in matlab you can get edge image by below codes.
clc
clear
img = imread('1.png'); % read Image
gray = rgb2gray(img); % Convert RGB to gray-scale
edgeImage = edge(gray,'canny',0.09); % apply canny to gray-scale image
imshow(edgeImage) % Display result in figure(MATLAB)
In OpenCV you can use below code
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
Mat img = imread("1.png");
Mat gray;
cvtColor(img, //BGR form image
gray, //Mat for gray(destination)
CV_BGR2GRAY); //type of transform(in here BGR->GRay)
Mat edgeImage;
Canny(gray, //Input Array
edgeImage, //Output Array
40, // Lower threshold
120); //Upper threshold
namedWindow("Edge-Image"); //create a window for display image
imshow("Edge-Image",edgeImage); //Display edgeImage in window that in before line create
waitKey(0); //stick display window and wait for any key
return 0;
}
Here is a solution in Matlab using imdilate to close the contours and regionprops to get the closed objects area:
% Your code to start
img = imread('Image.png'); % read Image
gray = rgb2gray(img); % Convert RGB to gray-scale
edgeImage = edge(gray,'canny',0.09); % apply canny to gray-scale image
% First dilate to close contours
BW = imdilate(edgeImage, strel('disk',4,8));
% Then find the regions
R = regionprops(~BW, {'Area', 'PixelIdxList'});
% Find the second biggest region (the biggest is the background)
[~, I] = sort([R(:).Area], 'descend');
Mask = zeros(size(img));
Mask(R(I(2)).PixelIdxList) = 1;
% Display
clf
imshow(Mask)
An the result is:
Best,
First close the contour with morphological closing since you can't find it now as it is not really a distinct contour, but a part of the larger one.
After closing, just use the findContours() function and use its output to get the area of each contour and eventually find the maximum one by using the contourArea() function.
I need a little help guys in Matlab in Matrix Dimensions,
I Have two images imported by imread function:
im1 = imread('1.jpg');
im2 = imread('2.jpg');
im1 is the reference image, while im2 is the Noisy image.
In the workspace window, Matlab shows the im2 Dimensions like this: 768x1024x3
while im2 displayed as: 768x1024
They are both RGB, there's no greyscale images,
In fact the second image is the a compressed image (performed compression algorithm on it ) while the first image is natural JPEG Image, untouched
and for calculating MSE/PNSR for both images, the matrix dimensions must be the same.
I Will need to transform im1 dimensions to be 3d like the first image (768x1024)
I tried this functions (squeeze, reshape) and with no success
You were on the right track with repmat. Here's the correct syntax:
im2 = repmat(im2, [1 1 3]);
This says you want 1 replicate along the first dimension, 1 replicate along the second dimension, and 3 replicates along the third dimension.
Are you sure that both are RGB images because im2 has only one channel and it looks grayscale but it can also be a colormap image in that case try
[im2, map] = imread('im2.jpg');
and see if anything is appearing in map variable. If the image is indeed colormap image, the map variable should be of size 256 X 3.
What donda has suggested is repeating the grayscale channel 3 times to make it of size 768x1024x3. Another possibility is that noisy image was created by converting RGB image to grayscale or by taking green channel of RGB image. Verify the source of the image in that case.
About PSNR computation I have a feeling that there is some problem with your code. I have given my code below use this and see if it works. Get back to me if you face any problem.
function [Psnr_DB] = psnr(I,I_out)
I = double(I);
I_out = double(I_out);
total_error = 0;
for iterz = 1:size(I,3)
for iterx = 1:size(I,1)
for itery = 1:size(I,2)
total_error = total_error + (I(iterx,itery,iterz)-I_out(iterx,itery,iterz))^2;
end
end
end
MSE = total_error/numel(I);
Psnr = (255^2)/MSE;
Psnr_DB = 10*log10(Psnr) %#ok<NOPRT>
I'm trying to retrieve the luminance component of a set of 'tif' images in matlab.
The code is bellow:
function [defaultImages] = readImgLum(nFiles)
% readImgLum reads a specified number of images in 'tif' format
% and retrieves the luminance component
narginchk(1, 1);
defaultImages = cell(nFiles, 1); % store all images in a vector
for i = 1 : nFiles
imagePreffix = int2str(i);
imageFullName = strcat(imagePreffix, '.tif');
image = imread(imageFullName);
imageYCbCr = rgb2ycbcr(image);
defaultImages{i} = squeeze(imageYCbCr(:,:,1));
end
Am I correctly extracting the luminance component?
As the comments have stated, there is no need for squeeze. This code also looks fine to me. However, if you want to skip computing all components of YCbCr just to extract the luminance, use the SMPTE / PAL standard for calculating luminance instead. This is actually done in rgb2gray in MATLAB if you want to look up the source.
In any case, assuming your images are unsigned 8-bit integer:
image = double(image);
defaultImages{i} = uint8(0.299*image(:,:,1) + 0.587*image(:,:,2) + 0.114*image(:,:,3));
BTW, image is a built-in command in MATLAB. It takes in any matrix, and visualizes it as an image in a new figure. I highly suggest you use another variable to store your temporary image as you may be calling further code later on that requires image as a function.
How can I convert a DICOM image into a grayscale image in matlab?
Thanks.
I'm not sure what specific DICOM image you are talking about that is not grayscale already. The following piece of code demonstrates how you read and display a DICOM image:
im = dicomread('sample.dcm'); % im will usually be of type uint16, already in grayscale
imshow(im, []);
If you want a uint8 grayscale image, use:
im2 = im2uint8(im);
However to keep as much of the precision as possible, it's best to do:
im2 = im2double(im);
To stretch the limits temporarily only when displaying the image, use:
imshow(im2, []);
To stretch the limits permanently (for visualization only not for analysis), use:
% im3 elements will be between 0 and 255 (uint8) or 0 and 1 (double)
im3 = imadjust(im2, stretchlim(im2, 0), []);
imshow(im3);
To write the grayscale image as jpg or png, use:
imwrite(im3, 'sample.png');
UPDATE
If your version of Matlab does not have im2uint8 or im2double, assuming that your DICOM image is always uin16 a quick workaround to convert the DICOM image to a more manageable format would be:
% convert uint16 values to double values
% im = double(im);
% keep the current relative intensity levels for analysis
% involving real values of intensity
im2 = im/2^16
% if displaying, create a new image with limits stretched to maximum
% for visualization purposes. do not use this image for
% calculations involving intensity value.
im3 = im/(max(im(:));