I just imported an image taken from my iphone 7 onto matlab. It turns out that the image has 3d size instead of 2d.
boxImage1 = imread('IMG_5175.jpg');
boxImage1 480x640x3 921600 uint8
Can anyone explain why the size of image is in 3d instead of just two. I am trying to run object detection tools on a set of images to extract relevant objects.
Thanks,
As pointed out in the comments, the three dimensions corresponds with the R, G and B channels. Have a look into the matlab documentation:
If the file contains a truecolor image, then A is an m-by-n-by-3 array.
Converting it to grayscale, using rgb2gray, is often a good idea, but it may depend on your application:
I = rgb2gray(boxImage1); % 480x640 matrix
Related
I have a 16bit voxel data set from which I need to extract the integer values for each voxel. The data set can be downloaded from here, it is the 'Head Aneuyrism 16Bits' data set (You need to click on the blood vessels image to download the 16bit version). Its size is 512x512x512, but I don't know whether it is greyscale or color, nor if that matters. Looking at the image on the website I'd guess that it is color, but I am not sure whether the image should be taken literally.
A related question on SO is the following: How can I read in a RAW image in MATLAB?
and the following on mathworks: http://www.mathworks.com/matlabcentral/answers/63311-how-to-read-an-n-dimensioned-matrix-from-a-binary-file
Thanks to the information in the answers to these questions I managed to extract some information from the file with matlab as follows:
fileID=fopen('vertebra16.raw','r');
A=fread(fileID,512*512*512,'int16');
B=reshape(A,[512 512 512]);
I don't need to visualise the image, I only need to have the integer values for each voxel, but I am not sure whether I am reading the information in the correct way with my script.
The only way I found to try and check whether I have the correct voxel values is to visualise B using the following:
implay(B)
Now, with the code above, and then using implay(B) I get a black and white movie with a white disc in the center and black background and some black pixels moving in the disc (I tried to upload a frame of the movie, but it didn't work). Looking at the image on the website from which I downloaded the file, the movie frames I get seem quite different from that image, so I'd conclude that I do not have the correct voxel values.
Here are some questions related to my problem:
Do I need to know whether the image is in grey scale or color to read the voxel values correctly?
On the data set website there is only written that the data set is in 16bit format, so how do I know whether I am dealing with signed or unsigned integers?
In the SO question linked to above they use 'uint8=>uint8'. I could not find this in the matlab manual, so I wonder whether 'uint8=>uint8' is an obsolete matlab notation for 'uint8' or if it does something different. I suspect that it does something different since if I use 'int16=>int16' instead of 'int16' in my code above I get a completely black movie with implay.
It looks like you read the data correctly.
The problem when displaying it is the scale of the values. implay seems to assume the values to be in [0,1] and therefore clamps all values to be in that range, where are your data range is [0,3000].
Simply doing
B = B / max(B(:))
will rescale your data to [0,1] and looking at the data again with
implay(B)
shows you something much more sensible.
Let's say i have an image like that one:
After some quick messing around, i got a binary image of the axe, like that:
What is the easiest/fastest way to get the contour of that image using GNU/Octave?
In Octave you can use bwboundaries (but I will welcome patches that implement bwtraceboundaries)
octave:1> pkg load image;
octave:2> bw = logical (imread ("http://i.stack.imgur.com/BoQPe.jpg"));
octave:3> boundaries = bwboundaries (bw);
octave:4> boundaries = cell2mat (boundaries);
octave:5> imshow (bw);
octave:6> hold on
octave:7> plot (boundaries(:,2), boundaries(:,1), '.g');
There are a couple of differences here from #Benoit_11 answer:
here we get the boundaries for all the objects in the image. bwboundaries will also accept coordinates as input argument to pick only a single object but I believe that work should be done by further processing your mask (may be due to the jpeg artifacts)
because we get boundaries for all objects, so you get a cell array with the coordinates. This is why we are using dots to plot the boundaries (the default is lines and it will be all over the image as it jumps from one object to other). Also, it is not documented whether the coordinates given are for the continuous boundary, so you should not assume it (again, why we plot dots).
the image that is read seems to have some artifacts, I will guess that is from saving in jpeg.
You can use bwtraceboundary in the Image package. Here is the Matlab implementation but that should be pretty similar using Octave:
First estimate starting pixel to look for boundary and then plot (BW is the image). (Check here )
dim = size(BW);
col = round(dim(2)/2)-90;
row = min(find(BW(:,col)));
boundary = bwtraceboundary(BW,[row, col],'N');
imshow(BW)
hold on;
plot(boundary(:,2),boundary(:,1),'g','LineWidth',3);
Output:
I'm working on a PIV-Workflow and I'm currently pre-processing the images. I need to get rid of the perspective distortion in the images. I do have the "image processing toolbox" and the "camera calibrator". I already got rid of the lens distortion with "undistortImage();" and the cameraParams object, which is inferred through a chessboard pattern.
First Question: Is it possible to use the cameraParams object to distort the image perspectively, so that my chessboard is rectified in the image?
Second Question: Since I were not able to use the cameraParams object, I tried to use the transformation functions manually. I tried to use pairs of control-points (with cpselection tool, the original image and a generated chessboard-image) and the fitgeotrans(movingPoints, fixedPoints, 'projective'); function to get my tform-object. However I always get the error message:
Error using fitgeotrans>findProjectiveTransform (line 189)
At least 4 non-collinear points needed to infer projective transform.
Error in fitgeotrans (line 102)
tform = findProjectiveTransform(movingPoints,fixedPoints);
I tried a lot of different pairs of control-points (4 pairs or more). But I'm still getting this error. I believe I must overlook something here.
Any help is appreciated, thank you.
Stephan
If you are using one of the calibration images, then all the information you need is in the cameraParams object.
Let's say you are using calibration image 1, and let's call it I.
First, undistort the image:
I = undistortImage(I, cameraParams);
Get the extrinsics (rotation and translation) for your image:
R = cameraParams.RotationMatrices(:,:,1);
t = cameraParams.TranslationVectors(1, :);
Then combine rotation and translation into one matrix:
R(3, :) = t;
Now compute the homography between the checkerboard and the image plane:
H = R * cameraParams.IntrinsicMatrix;
Transform the image using the inverse of the homography:
J = imwarp(I, projective2d(inv(H)));
imshow(J);
You should see a "bird's eye" view of the checkerboard. If you are not using one of the calibration images, then you can compute R and t using the extrinsics function.
Another way to do this is to use detectCheckerboardPoints and generateCheckerboardPoints, and then compute the homography using fitgeotform.
If I have an image, how can I obtain the values of each pixel in that image using matlab
Thanks.
Images are matrices (2D if grayscale, 3D if colored) in MATLAB.
You can use x(i,j) to access a pixel at location (i,j) in a grayscale image.
If the image is colored, you can use x(i,j,:) to access the r, g, b values in a 3-vector, respectively. If you need individual channels, then, you can use x(i,j,1) for red for example.
You may read this page to learn more.
You can use reshape to extract all the pixel values of the image into a vector with pixel values:
frame = imread('picture.jpg');
frame_size = size(frame);
allpixels = reshape(frame, frame_size(1)*frame_size(2), frame_size(3))
This can be useful when you want to vectorize your Matlab code (to avoid a for loop that goes through every pixel). To get back the original image representation:
frame2 = reshape(allpixels, frame_size);
to get the values at pixel(1,1) we simply write image(1,1).
I am working on Image Inpaiting on video project and i am selecting the portion of the image on a screen(ROI) as a rectangle and i am inpaiting that portion of the image. Now i want to save five previous frame from live video(that i can do it) and save the pixels value of that ROI of five frame/image on five different array. I will use that array to generate the background and remove the foreground object.
Any one know how i can save pixel value in array for that selected area?
Thanks in advance.
C++ interface of opencv use cv::Mat for storing image pixel.
The following code shows you how to declare a matrix B "pointing" to a ROI of matrix A.
Matrices are images. ROI is a rectangle (x=0;t=0;width=0;height=100). Use opencv highgui function to save your image.
cv::Mat A(640,480,CV_8C3);
cv::Rect rect(0,0,100,100);
cv::Mat B = A(rect);
cv::imwrite("my_roi.pbg",B);
If you need to read frames from a video, use cv::VideoCapture cap and cap >> frame to grab and retrieve each images as cv::Mat. If you want to go to different position in your video file use cv::VideoCapture::set(..,CV_FRAME_MSEC) , read manual.