I am trying to implement the JBIG compression for some images. I just want to know the compression ratio achieved by the algorithm. For this, I am using JBIG-KIT by Markus K.
https://www.cl.cam.ac.uk/~mgk25/jbigkit/
Also, there is a MATLAB implementation available that I am using the code pasted below:
Can you please tell me the questions regarding the following MATLAB code? It is code from the wavelet toolbox with paths and commands added for the JBIG-KIT's executables.
function [y,nbr_bits] = perform_jbig_coding(x)
% perform_jbig_coding - perform binary image coding
% [y,nbr_bits] = perform_jbig_coding(x);
% It requires pbmtojbg and jbgtopbm executable.
% Copyright (c) 2006 Gabriel Peyr
name_pbm = 'b.pbm';
name_jbg = 'c.jbg';
if size(x,1)>1 && size(x,2)>1
% forward transform
% save as pbm
imwrite(rescale(x), name_pbm, 'pbm');
% convert to jgib
!/Users/sahilsharma/Documents/MATLAB/JBIG/pbmtojbg -q b.pbm c.jbg
% read jbig file
fid = fopen(name_jbg); %Here%
if fid<0
error('Unable to open Jbig file.');
end
[y,cnt] = fread(fid, Inf);
fclose(fid);
nbr_bits = length(y)*8;
% remove tmp files
!del c.jbg
!del b.pbm
else
% backward transform
fid = fopen(name_jbg, 'wb');
if fid<0
error('Unable to open Jbig file.');
end
fwrite(fid, x);
fclose(fid);
% convert to pbm
!/Users/sahilsharma/Documents/MATLAB/JBIG/jbgtopbm c.jbg b.pbm
% read pbm
y = imread(name_pbm);
% remove tmp files
!del c.jbg
!del b.pbm
nbr_bits = -1;
end
I have added the path here to run my code. It is working now. However I have two doubts,
!del command is not working, MATLAB is telling that "Command not found:del". So I thought that "rm" might work here. However, that is also not working, if you have any idea how will I be able to delete those files, please do answer.
[y,cnt] = fread(fid, Inf); (I have commented %Here% in code), am I getting encoded values here? Cause I need to find the compression ratio achieved by JBIG. JBIG uses context-based arithmetic encoding. So I wanted to know if the [y,cnt] reads the encoded data. Through this, I would directly be able to get CR as I know the original size.
'x' is a binary image, currently, I am using an image of size 740x628 (size(x) = [740 628]). cnt = 115392 and y= 14424x1 double. I wanted to have a confirmation about 'y', that if it is the encoded image. If it is then my Compression Ratio becomes (740*628)/115392. The operating system that I am using is macOS.
Oh very sorry 115392 is the value of 'nbr_bits' and 'cnt' = 14424.
Once you get your numbers straight, there doesn't seem to be an issue. You are compressing a 57 KB bi-level image to a 14 KB JBIG compression of that image. Well within the realm of expectation.
Related
The following MATLAB script generates random locations within a 300x400 array and codes those locations with values from 1-12. How can I convert this non-spatial array to a geotiff? I hope to use the geotiff output to perform some trial analyses. Any projected coordinate system (e.g. UTM) would do for this analysis.
I have tried using geotiffwrite() without success using the following implementation:
out = geotiffwrite('C:\path\to\file\test.tif', m)
Which yields the following error:
>> test
Error using geotiffwrite
Too many output arguments.
EDIT:
The main problem I am encountering is a lack of inputs into the geotiffwrite() function. I am unsure how to deal with this problem. For example, I have no A or R variable because the array has no spatial reference. As long as each pixel is georeferenced somewhere, I do not care what the spatial reference is. The purpose of this is to create a sample dataset that I can experiment with using MATLAB spatial functions.
% Generate a totally black image to start with.
m = zeros(300, 400, 'uint8');
% Generate 1000 random locations.
numRandom = 1000;
linearIndices = randi(numel(m), 1, numRandom);
% Set those locations to be "white".
m(linearIndices) = randi(12, [numel(linearIndices) 1]);
% Display it. Random locations will appear white.
image(m);
colormap(gray);
I believe your question has a very simple answer. Skip the out-variable when you call geotiffwrite. That is, use:
geotiffwrite('C:\path\to\file\test.tif', m)
Instead of
out = geotiffwrite('C:\path\to\file\test.tif', m)
This is example of a working code using geotiffwrite, taken from the documentation. As you can see, there is no output variable there:
basename = 'boston_ovr';
imagefile = [basename '.jpg'];
RGB = imread(imagefile);
worldfile = getworldfilename(imagefile);
R = worldfileread(worldfile, 'geographic', size(RGB));
filename = [basename '.tif'];
geotiffwrite(filename, RGB, R)
figure
usamap(RGB, R)
geoshow(filename)
Update:
According to the documentation, you need at least 3 input parameters. The correct syntax is:
geotiffwrite(filename,A,R)
geotiffwrite(filename,X,cmap,R)
geotiffwrite(...,Name,Value)
From documentation:
geotiffwrite(filename,A,R) writes a georeferenced image or data grid,
A, spatially referenced by R, into an output file, filename.
Please visit this link to see how to use the function.
I am having a bit of trouble with a specific file i/o in matlab, I am fairly new to it still so some things are still a bit of a mystery to me. The input file is structured as so:
File Name: Processed_kplr003942670-2010174085026_llc.fits.txt
File contents- 6 Header Lines then:
1, 2, 3
1, 2, 3
basically a matrix of about [1443,3] with varying values
now here is the matrix that I'm comparing it to:
[(0123456, 1, 2, 3), (0123456, 2, 3, 4), (etc..)]
Now here is my problem, first I need to know how to properly do the file input in a way which can let me compare the ID number (0123456) that is in the filename with the ID value that is in the matrix, so that I can compare the other columns of both. I do not know how to achieve this in matlab. Furthermore, I need to be able to loop over every point in the the matrix that matches up to the specific file, for example:
If I have 15 files ranging from 'Processed_0123456_1' to 'Processed_0123456_15' then I want to be able to read in the values contained in 'Processed_0123456_1'and compare them to ANY row in the matrix that corresponds to that ID (0123456). I don't know if maybe accumaray can be used for this, but as I said I'm not sure.
So the code must:
-Read in file
-Compare file to any point in the matrix with corresponding ID
-Do operations
-Loop over until full list of files in the directory are read in and processed, and output a matrix with the results.
Thanks for any help.
EDIT: Exact File Sample--
Kepler I.D.-----Channel
[1161345]--------[84]
-TTYPE1--------TTYPE8------------TTYPE4
['TIME']---['PDCSAP_FLUX']---['SAP_FLUX']
['BJD - 2454833']--['e-/s']--------['e-/s']
CROWDSAP --- 0.9791
630.195880143,277165.0,268233.0
630.216312946,277214.0,268270.0
630.23674585,277239.0,268293.0
630.257178554,277296.0,268355.0
630.277611357,277294.0,268364.0
630.29804426,277365.0,268441.0
630.318476962,277337.0,268419.0
630.338909764,277403.0,268481.0
630.359342667,277389.0,268463.0
630.379775369,277441.0,268508.0
630.40020817,277545.0,268604.0
There are more entries than what was just posted but they go for about 1000 lines so it is impractical to post that all here.
To get the file ID, use regular expressions, e.g.:
filename = 'Processed_0123456_1';
file_id_str = regexprep(filename, 'Processed_(\d+)_\d+', '$1');
file_num_str = regexprep(filename, 'Processed_\d+_(\d+)', '$1')
To read in the file contents, assuming that it's all comma-separated values without a header, use textscan, e.g.,
fid = fopen(filename)
C = textscan(fid, '%f,%f,%f') % Use as many %f specifiers as you have entries per line in the file
textscan also works on strings. So, for example, if your file contents was:
filestr = sprintf('1, 2, 3\n1, 3, 3')
Then running textscan on filestr works like this:
C = textscan(filestr, '%f,%f,%f')
C =
[2x1 int32] [2x1 int32] [2x1 int32]
You can convert that to a matrix using cell2mat:
cell2mat(C)
ans =
1 2 3
1 3 3
You could then repeat this procedure for all files with the same ID and concatenate them into a single matrix, e.g.,
C_full = [];
for (all files with the same ID)
C = do_all_the_above_stuff;
C_full = [C_full; C];
end
Then you can look for what you want in C_full.
Update based on updated OP Dec 12, 2013
Here's code to read the values from a single file. Wrap this all in the the loop that I mentioned above to loop over all your files and read them all into a single matrix.
fid = fopen('/path/to/file');
% Skip over 12 header lines
for kk = 1:12
fgetl(fid);
end
% Read in values to a matrix
C = textscan(fid, '%f,%f,%f');
C = cell2mat(C);
I think your requirements are too complicated to write the whole script here. Nonetheless, I will try to give some pointers to help. Disclaimer: None of this is tested, just my best guess. Please expect syntax errors, etc. I hope you can figure them out :-)
1) You can use the textscan function with the delimiter option to get data from the lines of your file. Since your format varies as it does, we will probably want to use...
2) ... fgetl to read the first two lines into strings and process them separately using texstscan. Such an operation might look like:
fid = fopen('file.txt','w');
tline1 = fgetl(fid);
tline2 = fgetl(fid);
fclose(fid);
C1 = textscan(tline1,'%s %d %s','delimiter','_'); %C1{2} will be the integer we want
C2 = textscan(tline2,'%s %s'),'delimiter,':'); %C2{2} will be the values we want, but they're still a string so...
mat = str2num(C2{2});
3) Then, for the rest of the lines, we can use something like dlmread:
mat2 = dlmread('file.txt',',',2,0);
The 2,0 specifies the offset in 0-based rows,columns from the start of the file. You may need to look at something like vertcat to stitch mat and mat2 together.
4) The list of files in the directory can be found with the dir command. The filename is an attribute of the structure that's returned:
dirlist = dir;
for i = 1:length(dirlist)
filename = dirlist(i).name
%process your files
end
You can also pass matching strings to dir, like so:
dirlist = dir('*.txt');
which will find all of the files with extension .txt.
5) You can very easily loop through the comparison matrix:
sze = size(comparisonmatrix);
for i = 1:sze(1)
%compare comparisonmatrix(i,1) to C1{2}
%Perform whatever operations you need
end
Hope that helps!
I have a code to crop connected components of input image, input, by finding the boundary conditions from a binary image's labelled map, labelledmap ([labelledmap, labelcount] = bwlabel(hvedged, 8);)
I'm new to matlab so this might sound stupid..
The problem is, I am unable to store different cropped images in the same variable, Because matlab seems to merge the ends of the already existing image and the new cropped image, i.e, it is storing the complete map between the two cropped images, the way i see it :/
This is the output Using different variables for storing cropped image (the kind of output i want)
Output Using different variables for storing cropped image
This is the output i'm getting by storing the cropped image in the same variable(not helpful)
Output when storing cropped image in the same varible
I tried using an array of size equal to total number of labels produced but it's giving the same result.. also i tried clearvars for clearing the output token image, ltoken, after every iteration of the loop but it's not helping
So, is there any possible way to display individual cropped images.. also the number of cropped images might be in thousands so i want to use a loop to code their cropping mechanism
here is a part of the code attached.. thanks in advance ;)
for h=1:labelcount
for i=1:r
for j=1:c
if labelledmap(i,j)==h
if i<ltop
ltop=i;
end
if i>lbottom
lbottom=i;
end
if j<lleft
lleft=j;
end
if j>lright
lright=j;
end
end
end
end
if ltop>5
ltop=ltop-5;
end
if lbottom<r-5
lbottom=lbottom+5;
end
if lleft>5
lleft=lleft-5;
end
if lright<c-5
lright=lright+5;
end
lwidth=lright-lleft;
lheight=lbottom-ltop;
ltoken=imcrop(input,[lleft ltop lwidth lheight]);
figure('Name', 'Cropped Token'), imshow(ltoken);
clearvars ltoken;
end
you need to initialize ltop lbottom lleft and lright for each iteration of label h. I think this is the reason why you get the cropped images "glued" together.
It is EXTREMELY inefficient to go through all the pixels for each and every one of your labels. Especially when you are expected to have many labels.
Use regionprops to get the 'BoundingBox' property for each label.
Here's an example
st = regionprops( labelledmap, 'BoundingBox' );
imlist = cell( 1, numel(st) ); % pre-allocate
for ii=1:numel(st)
r = st(ii).BoundingBox;
% I understand you want to increase the BB by 5 pixels at each side:
r(1:2) = r(1:2) - 5; % start point moves -5
r(3:4) = r(3:4) + 10; % width and height increases by 10
imlist{ii} = imcrop( input, r );
end
I'm still a bit in shock by your code that explicitly loops through all pixels just for finding the bouding box. This is NOT the matlab way of doing things.
If you insist on NOT using regionprops here's a more Matlab-ish way of finding the ii-th bounding box:
imsk = (labeledmap == ii); % create a binary map with True for ii-th region
xFlat = any(imsk,1); % "flattening" imsk on the x-axis
lleft = find( xFlat, 1, 'first' );
lright = find( xFlat, 1, 'last' );
yFlat = any(imsk, 2);
ltop = find( yFlat, 1, 'first' );
lbottom = find( yFlat, 1, 'last' );
No loops at all over image coordinates.
I have a .txt file containing 1000 rows and 100000 columns. A 10GB text file, of simulation results (real numbers) that I need to analyse.
My data is of the form: [0.5 0.3 0.45 .. ;
0.4 0.22 0.21587 .. ;
0.1359 1.054 1.1 ... ]
(separated by spaces and lines)
If I try loading (in Matlab) the entire file into a matrix at once using A=load('Data.txt'), I get an error message: "Insufficient memory", which I assume means - RAM (right?).
I wish to read than only one line from the file at a time, into a 1d array. How do I do that?
I already tried different versions of A=load('Data.txt')(1,:) or A=load('Data.txt'(1,:)) etc.
An answer in C code code would also be appreciated. Thank you.
See this answer. If your file is that big, you should not try to load it all at once. You should read it line by line. If this still doesn't work, you should take a look at the csvread function.
Edit:
Also this link could be quite helpful
2nd Edit:
Try the Matfile io
If efficiency is not too much of a concern, you can use an eval statement.
fid = fopen('output.txt'); % Open the file
numRun = 10; % The number of simulations
for ii = 1:numRun
ln = fgetl(fid);
eval( sprintf('a=%s;', ln) );
% Do stuff
end
However, I think that a better way for you to do it would be to give each run its own special file, and then read that like normal. That way you don't have to worry about ghost variables from eval statements or overall eval overhead.
fid = fopen('output.txt'); % Open the file
numRun = 10; % The number of simulations
for ii = 1:numRun
ofid = fopen(sprintf('output%i.txt', ii), 'w')
ln = fgetl(fid); % Read the line
fprintf( ofid, ln );
fclose( fid );
end
This should do what you're looking for:
fid = fopen('Data.txt');
while~feof(fid)
line = fgetl(fid);
C = textscan(line, '%f %f %f', 'Delimiter', ';');
data = cell2mat(C);
... Do you processing below
end
This will process the data line by line. I'm also assuming that you data is delimited by the ; char, and that you know the length of each line hence the (%f %f %f). For example, this:
0.5 0.3 0.45; 0.4 0.22 0.21587; 0.1359 1.054 1.1
will turn into this:
0.5000 0.3000 0.4500
0.4000 0.2200 0.2159
0.1359 1.0540 1.1000
The goal would be the same : read each line at a time from the data, and - calculate it's sum. – user1611107
If you're looking to find the sum of each line, you can add the following:
lSum = sum(data);
I read a few books and articles about Convolutional neural network, it seems I understand the concept but I don't know how to put it up like in image below:
(source: what-when-how.com)
from 28x28 normalized pixel INPUT we get 4 feature maps of size 24x24. but how to get them ? resizing the INPUT image ? or performing image transformations? but what kind of transformations? or cutting the input image into 4 pieces of size 24x24 by 4 corner? I don't understand the process, to me it seem they cut up or resize the image to smaller images at each step. please help thanks.
This is matlab help file for CONV2 function, which use in CNN Matlab (to get convolutional layers). Read it carefully and you will see your answer.
%CONV2 Two dimensional convolution.
% C = CONV2(A, B) performs the 2-D convolution of matrices A and B.
% If [ma,na] = size(A), [mb,nb] = size(B), and [mc,nc] = size(C), then
% mc = max([ma+mb-1,ma,mb]) and nc = max([na+nb-1,na,nb]).
%
% C = CONV2(H1, H2, A) convolves A first with the vector H1 along the
% rows and then with the vector H2 along the columns. If n1 = length(H1)
% and n2 = length(H2), then mc = max([ma+n1-1,ma,n1]) and
% nc = max([na+n2-1,na,n2]).
%
% C = CONV2(..., SHAPE) returns a subsection of the 2-D
% convolution with size specified by SHAPE:
% 'full' - (default) returns the full 2-D convolution,
% 'same' - returns the central part of the convolution
% that is the same size as A.
% 'valid' - returns only those parts of the convolution
% that are computed without the zero-padded edges.
% **size(C) = max([ma-max(0,mb-1),na-max(0,nb-1)],0).**