I loaded an 8bit grayscale image into octave with imread, then I saved it in ascii format and got a giant list of all of it's values. Then I dithered it with a 2x2 matrix in Java and printed out a list of each dithered matrix all on one line.
If the matrix for a pixel in my program turns out to be this:
0 2
3 1
Then the output that my program generates looks like:
0 2 3 1
Then I have all of the matrices for each pixel in that format all on one line. How can I load this into octave to see the final dithered image?
I was messing around with octave and created a simple matrix like the first one I showed and saved that to a file, then I was able to put it all on one line and load it up again just fine. I tried to then replace the matrix in that file with the matrix my program generated, but octave doesn't seem to be loading that in. The matrix it tried to load it to doesn't get changed at all.
I dont think I fully understood your question, but if you are having trouble interacting with the file system, I suggest using the functions dlmread and dlmwrite.
The follow code should provide an example to get you started:
%Random 4 by 4 matrix
M = rand(4,4)
%Write matrix to file system
dlmwrite("filename.txt",M);
%Read it back and store in an other variable
M2 = dlmread("filename.txt")
Related
Let me explain.
My program takes an x-ray in a format of the x-ray detector ".his" which goes from 0 to 65535, and from those values it can tell you how much of a certain material is in each pixel "4 cm of aluminum" for example.
It does that for every pixel and you end up with a matrix that tells you how much of a given material is there, and you can visualize that matrix and see only fat tissue in an image without the bones blocking your view, it's very cool I know.
What I want to do now is to save that matrix as an image so that I can analyse and modify that image with programs like Image J, but I also want that if I see the pixel value I see the original value, I want to see "4" and know that pixel shows 4 cm of lungs or whatever material I'm working on.
Is that possible?, my professor seems to think that it is but he's not sure how to do it, and figure that out is my job anyway.
It should be possible since with Image J I can open the ".his" format and I can do just that, I can see the values from 0 to 65535, provided I say Image J that the image is 16 bit unsigned and other properties of that kind of files, but I wouldn't know how to do that for a Matlab variable.
Thanks a lot.
So if I understand correctly, you want to save an image that also contains arbitrary metadata on every pixel (in this case an integer).
If you use an image format like PNG you could encode that extra data into the alpha channel (which would be nearly imperceptible with a value like 4/255 away from fully opaque), but you'd have to be careful when editing the image that you don't change the alpha channel by mistake.
However, this is rather finnicky and would be cumbersome to implement in Matlab.
Instead I would suggest simply saving a standard image and a text file (or binary file) alongside it with the data you want.
I'm trying to make Scilab receive a certain JPEG image then transform it into a matrix of values between 0 and 255 (normal 8bit depth image) and then rearrange those values into smaller depths. The proposal is to make all the options from 1bit to 7bits which translates into 2, 4, 8, 16, 32, 64 and 128 different levels of color for them respectively.
We're doing it with greyscale images to make things simpler, since we can simply get any of the 3 channels and work with it as a matrix of rows and columns. I know there are many better ways of doing this, but I need to do it using Scilab since it's for a image processing course at University (signals and linear systems subject from Electrical Engineering to be exact).
What I could come up with, and it worked fine for the test-matrices that I tried, is this:
function y=bits(x,p)
[rows, columns]=size(x);
y=zeros(rows,columns);
aux=round(linspace(0,255,2^p)); //define which values the output can have
for i=1:rows //varies rows
for j=1:columns //varies columns
[aux2,minpos]=min(abs(aux-x(i,j)));//calculates the closest value between the input and the possible output values
y(i,j)=aux(minpos); //get the calculated closest value and puts it at the output
end
end
endfunction
What I can't understand is why it works fine for any hand-made matrix but when I try to send it something bigger (I mean, which more rows and columns) it gives the "Submatrix incorrectly defined." error at line 8 which is the " y(i,j)=aux(minpos);" line.
Edit: Just to add, I'm importing the image using "imread", which is a function of SIVP.
Any help is appreciated, thanks in advance =)
I could fix it with the following at the beginning of the function:
x=x(:,:,1);
x=double(x);
=).
So I'm sure this is an incredibly simple question, but I'm having trouble reading and displaying data from a .bin file. Basically, I have an image (256x256, 8 bits per pixel) that I'm trying to read in and display. While I can get this to work for a .jpg or .tif, I can't get it to work for a .bin file. Here's my code as of now:
file = fopen('image.bin', 'r');
A = fread(file);
imshow(A) %not sure if this is correct...
% imshow(file) doesn't work
% imshow('image.bin') doesn't work either
fclose(file);
Any ideas?
I'm going to assume that your .bin file consists of raw image intensities that are stored in a binary file. Your fread call will simply read the contents of the file into an array, but you need to be careful. By default, the values will be read in as 64-bit double values in MATLAB so what will happen is that a single double value will contain 8 image pixels. As such, what you need to do is modify how the values are being read in with fread. Specifically, you need to do this:
A = fread(file, 256*256, 'uint8=>uint8');
This is saying that you are going to read a total of 256 x 256 image pixels, where the input binary file stores the data in unsigned 8-bit integers. After, the data is read into MATLAB as the same type. Now, what you need to do next is to reshape the array so that it becomes a 256 x 256 image.
However, because fread reads in the data in column-major, each row of this reshaped image would be placed into the columns, and so you need to transpose the reshaped matrix when you're done. Specifically:
A = reshape(A, 256, 256).';
Now, A would be your 256 x 256 image that you are seeking. You can now show this image with imshow(A);.
I am having an issue reading a single image of a stacked tiff in using imread. The tiff is 128-by-126. It reads in just fine with ImageJ, but I try reading it into Matlab for some processing and it creates an odd streak in the center of the image. With the origin of the image in the top left, rows 63 and 64 are repeated as rows 65 and 66, and the last two rows of the image, 125 and 126 are cut off. I can tell this is happening by visual comparison of the image displayed in matlab to the image displayed in ImageJ.
If I take the same tiff stack, and save the first frame in ImageJ, I don't have this issue. Even when displaying the outputted matlab image using ImageJ, I see the same issue. However, I would like to automate the process to save images from several tiff stacks as single tiff files, which I can't do in ImageJ, so I turned to Matlab and ran into this issue. I have included my code below. I tried reading the tiff in two different ways and got the same error. It seems to be related to the tiff stack and how matlab reads in the tiffs. I am using Matlab R2012b.
I have included links below to the static ImageJ image I am seeing and the static matlab image I am seeing. I have also included a link for loading the stacked tiff file that is generating these issues for me.
Note: When I have ImageJ output each frame as an individual tiff and I open the first frame from that output in matlab using the same code below, the image is correctly displayed. The error only occurs when reading in the first frame from the image stack in Matlab.
StackOverflow doesn't support embedding TIFF files, but you can view and download them from these links:
Stacked Tiff File - Data I am working with
What the first frame should look like - ImageJ
What I am seeing when loading the first frame in MATLAB
Code Used to Generate the Image
fname='C:\FileLocation\pcd144_012.tif';
im1=imread(fname,1)
imagesc(im1);
axis image; colormap gray;
I tried reading in the image as a tiff object to see if it solved the problem and this didn't work either. The image has two strips, and the last two lines of the first strip are the same as the first two lines of the last strip, which is why the middle lines seem to be repeated. It seems matlab is indexing reading my image in wrong, likely because it is not a square image. Am I just doing something wrong, or does matlab have a bug with respect to reading in non-square tiffs? Any ideas or suggestions for improvement?
First of, I kinda agree with horchler, that is, there is something wrong in your header.
We can easily observe that the StripByteCounts (15872) does not match width*height (128*126). This could be the reason you see the repetition in row 63 - 64 and 65 - 66.
Since the RowPerStrip = 64 and StripOffsets = [8,15880] may indicate that you have a 128*124 graph, Matlab perhaps uses last two rows in the first 64 rows to pad the missing rows at the beginning of the rest of the rows. So the total row can be filled up to 126. Well, this is just my guess for how Matlab handles the disagreement between dimension and ByteCounts.
After all, to your question, imread indeed alters image in Matlab when reading TIFF without issuing any warning. Bad job in imread reading TIFF, Matlab.
After observing your TIFF frames in one of your links, the TIFF seems to actually have image data with dimension 128*126. So if you trust the dimension indicating in the header, you would probably use fread to read the frames in your TIFF instead of using shaky imfread.
fname='pcd144_012.tif';
tiffInfo = imfinfo(fname);
framIndex = 1;
tiffWidth = tiffInfo(framIndex).Width; % image width
tiffHeight = tiffInfo(framIndex).Height; % image height
tiffStartOffset = tiffInfo(framIndex).StripOffsets(1); % Image data offset start point
tiffEndOffset = tiffInfo(framIndex).StripOffsets(2); % Image data offset end point
fid = fopen(fname);
fseek(fid,tiffStartOffset,'bof');
im1 = fread(fid,tiffWidth*tiffHeight,'*uint16'); % We knew this from BitsPerSample
fclose(fid);
im1 = reshape(im1,tiffWidth,tiffHeight); % Reshape the image data array
figure
imagesc(im1);
colormap gray;
axis xy;
axis image;
Now, while this may solve the weird Matlab imread behavior, however, the above result still does not match the picture you showed in your second link. According to the picture in the second link, it has 300 frames but the one you attached in your first link only has 30 frames. Maybe we are all looking at the wrong picture?
I have an image that I want to divide in three parts and find the centroid of the parts separately and display them on original image, I used blkproc for dividing the image in [1 3] grids, but can't display the centroids. Here is the code I wrote,
i=imread('F:\line3.jpg');
i2=rgb2gray(i);
bw=im2bw(i2);
imshow(bw)
fun=#(x) regionprops(x,'centroid');
b=blkproc(bw,[1 3],fun);
But I can't get to display the centroids, as well as get their values. Any help will be much appreciated.
You can just use the plot command to plot over the top of the image.
Whatever you [X,Y] centroid coordinates are, say cx(1:3) and cy(1:3)
numCentroids is the number of centroids you are plotting.
hold on;
for ii = 1:length(numCentroids)
plot(cx(ii),cy(ii),'Marker','s','MarkerSize',10,'MarkerFaceColor','r','MarkerEdgeColor','k')
end
If you wanted to write more elegant code, you could run the plot command once across all your centroids and then make the line style type invisible. The answer I supplied should work though.
Here's an example image with made up centroids.
Strong recommendation - use blockproc instead of blkproc. It is better designed and easier to use.
Now, first of all, the second input to blockproc is the blocksize and not the grid size. So if you want to divide your image into [1 3] grid, which I understand as a single row of three blocks, then you should set your blocksize as:
blocksize = [size(i,1) ceil(size(i,2)/3)];
The second thing is to turn off the 'TrimBorder' parameter in blockproc. The code would look something like:
fun=#(x) regionprops(x,'centroid');
blocksize = [size(i,1) ceil(size(i,2)/3)];
b=blockproc(bw,blocksize,fun,'TrimBorder',false);
One minor thing - I would recommend not using the variable name 'i'. By default it represents the imaginary number i = sqrt(-1); in Matlab.