bmpinfoheader for writing BMP images - matlab

I'm trying to write a MATLAB code for writing file to BMP file.
I know I can use imwrite() function. But my task is to avoid it.
I need info about how to write bmpinfoheader? So far I only know that it is 14-bits array.

8-bit BMP
%---- BitMapfileHeader
fwrite(fid, hex2dec('42'), 'uchar'); % 'B' in ASCII code
fwrite(fid, hex2dec('4D'), 'uchar'); % 'M' in ASCII code
fwrite(fid, 54 + sz + 256 * 4, 'ulong'); % file size
fwrite(fid, 0, 'ushort'); % always 0
fwrite(fid, 0, 'ushort'); % always 0
fwrite(fid, 54 + 256 * 4, 'ulong'); % offset
%---- BitMapInfoHeader
fwrite(fid, 40, 'ulong'); % BitMapInfoHeader size
fwrite(fid, width, 'long'); % image width
fwrite(fid, height, 'long'); % image height (negative; positive=upside-down)
fwrite(fid, 1, 'ushort'); % always 1
fwrite(fid, 8, 'ushort'); % color bit
fwrite(fid, 0, 'ulong'); % compression
fwrite(fid, sz, 'ulong'); % image size
fwrite(fid, dpm, 'long'); % horizontal resolution (dpm)
fwrite(fid, dpm, 'long'); % vertical resolution (dpm)
fwrite(fid, 256, 'ulong'); % # of color index
fwrite(fid, 0, 'ulong'); % # of important color index
24-bit BMP
%---- BitMapfileHeader
fwrite(fid, hex2dec('42'), 'uchar'); % 'B' in ASCII code
fwrite(fid, hex2dec('4D'), 'uchar'); % 'M' in ASCII code
fwrite(fid, 54 + sz, 'ulong'); % file size
fwrite(fid, 0, 'ushort'); % always 0
fwrite(fid, 0, 'ushort'); % always 0
fwrite(fid, 54, 'ulong'); % offset
%---- BitMapInfoHeader
fwrite(fid, 40, 'ulong'); % BitMapInfoHeader size
fwrite(fid, width, 'long'); % image width
fwrite(fid, height, 'long'); % image height (negative; positive=upside-down)
fwrite(fid, 1, 'ushort'); % always 1
fwrite(fid, 24, 'ushort'); % color bit
fwrite(fid, 0, 'ulong'); % compression
fwrite(fid, sz, 'ulong'); % image size
fwrite(fid, dpm, 'long'); % horizontal resolution (dpm)
fwrite(fid, dpm, 'long'); % vertical resolution (dpm)
fwrite(fid, 0, 'ulong'); % # of color index
fwrite(fid, 0, 'ulong'); % # of important color index
Source - http://www.h6.dion.ne.jp/~fff/old/technique/matlab/matlab_V.html
Or look at the structure here
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx http://www.herdsoft.com/ti/davincie/davp3xo2.htm

Related

Formation of a bitonal image by the threshold Thr

I have a task - The formation of a bitonal image on the threshold of Thr. If the pixel brightness value exceeds the threshold, then it is replaced by the maximum (in our case by 255), otherwise by the minimum, i.e. by 0. But at the output, the image behaves strangely from the side, tell me how to fix it?
The result obtained
function decomp_new(array, thr, filename, FH, IH, RGBQUAD0, RGBQUAD1)
FID = fopen(filename, 'w');
fwrite(FID, FH.bfTYPE, 'uchar');
fwrite(FID, FH.bfSIZE, 'ulong');
fwrite(FID, FH.bfR1, 'uint8');
fwrite(FID, FH.bfR2, 'uint8');
fwrite(FID, FH.bfOFFBITS, 'ulong');
fwrite(FID, IH.biSIZE, 'ulong');
fwrite(FID, IH.biWIDTH, 'ulong');
fwrite(FID, IH.biHEIGHT, 'ulong');
fwrite(FID, IH.biPLANES, 'uint16');
fwrite(FID, 1, 'uint16'); %IH.biBITCOUNT
fwrite(FID, IH.biCOMPRESSION, 'ulong');
fwrite(FID, IH.biSIZEIMAGE, 'ulong');
fwrite(FID, IH.biXPELSPERMETER, 'ulong');
fwrite(FID, IH.biYPELSPERMETER, 'ulong');
fwrite(FID, IH.biCLRUSED, 'ulong'); %IH.biCLRUSED
fwrite(FID, IH.biCLRIMPORTANT, 'ulong');
fwrite(FID, IH.tmp, 'uint8');
fwrite(FID, RGBQUAD0.RED, 'uint8');
fwrite(FID, RGBQUAD0.GREEN, 'uint8');
fwrite(FID, RGBQUAD0.BLUE, 'uint8');
fwrite(FID, RGBQUAD0.RESERVED, 'uint8');
fwrite(FID, RGBQUAD1.RED, 'uint8');
fwrite(FID, RGBQUAD1.GREEN, 'uint8');
fwrite(FID, RGBQUAD1.BLUE, 'uint8');
fwrite(FID, RGBQUAD1.RESERVED, 'uint8');
for i = 1 : 3 : length(array)
B = array(i);
G = array(i+1);
R = array(i+2);
Y = 0.299 * R + 0.587 * G + 0.114 * B;
if (Y > thr)
fwrite(FID, 1, 'ubit1','ieee-be');
end
if (Y <= thr)
fwrite(FID, 0, "ubit1','ieee-be');
end
end
fclose(FID);
end

Image object width and height - Matlab

Based on this question Width and height of a rotated polyshape object - Matlab I was running the cool code. It can extract the height and width of the bounding box but how can I get the “real” object maximum height and width (which is not always the bounding box like in the image attached)?
Code:
clc;
clear all;
Image = imread('E:/moon.gif');
BW = imbinarize(Image);
BW = imfill(BW,'holes');
BW = bwareaopen(BW, 100);
stat = regionprops(BW,'ConvexHull','MinFeretProperties');
% Compute Feret diameter perpendicular to the minimum diameter
for ii=1:numel(stat)
phi = stat(ii).MinFeretAngle; % in degrees
p = stat(ii).ConvexHull * [cosd(phi),-sind(phi); sind(phi),cosd(phi)];
minRect = max(p) - min(p); % this is the size (width and height) of the minimal bounding box
stat(ii).MinPerpFeretDiameter = minRect(2); % add height to the measurement structure
width = minRect(1)
height = minRect(2)
end
You can try this code:-
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 25;
%===============================================================================
% Get the name of the first image the user wants to use.
baseFileName = 'A.jpg';
folder = fileparts(which(baseFileName)); % Determine where demo folder is (works with all versions).
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
%=======================================================================================
% Read in demo image.
rgbImage = imread(fullFileName);
% Get the dimensions of the image.
[rows, columns, numberOfColorChannels] = size(rgbImage);
% Display the original image.
subplot(2, 2, 1);
imshow(rgbImage, []);
axis on;
caption = sprintf('Original Color Image, %s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0.05 1 0.95]);
% Get rid of tool bar and pulldown menus that are along top of figure.
% set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
drawnow;
hp = impixelinfo(); % Set up status line to see values when you mouse over the image.
[rows, columns, numberOfColorChannels] = size(rgbImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
% grayImage = rgb2gray(rgbImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
grayImage = rgbImage(:, :, 1); % Take red channel.
end
% Display the image.
subplot(2, 2, 2);
imshow(grayImage, []);
axis on;
caption = sprintf('Gray Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo();
drawnow;
% Display the histogram of the image.
subplot(2, 2, 3);
histogram(grayImage, 256);
caption = sprintf('Histogram of Gray Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
grid on;
drawnow;
%=======================================================================================
binaryImage = grayImage < 150;
% Keep only the largest blob.
binaryImage = bwareafilt(binaryImage, 1);
% Display the masked image.
subplot(2, 2, 3);
imshow(binaryImage, []);
axis on;
caption = sprintf('Binary Image');
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
hp = impixelinfo();
drawnow;
% Get the bounding box of the blob.
props = regionprops(binaryImage, 'BoundingBox');
boundingBox = [props.BoundingBox]
% Display the original image.
subplot(2, 2, 4);
imshow(rgbImage, []);
axis on;
caption = sprintf('Original Color Image, %s', baseFileName);
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
% Plot the bounding box over it.
hold on;
rectangle('Position', boundingBox, 'LineWidth', 2, 'EdgeColor', 'r')

How to rotate image and axes together on Matlab?

Code 1 where flipping vertically and/or horizontally does not affect axes();
Code 2 where proposed solution does not yield the expected output
close all; clear all; clc;
x = [5 8];
y = [3 6];
C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
C2 = C(:,end:-1:1,:); %# horizontal flip
C3 = C(end:-1:1,:,:); %# vertical flip
C4 = C(end:-1:1,end:-1:1,:); %# horizontal+vertical flip
% https://stackoverflow.com/a/4010203/54964
subplot(2,2,1), imagesc(x,y,C)
subplot(2,2,2), imagesc(x,y,C2)
subplot(2,2,3), imagesc(x,y,C3)
subplot(2,2,4), imagesc(x,y,C4)
%% Rotations of axes() unsuccessfully
% https://stackoverflow.com/a/15071734/54964
figure
subplot(2,2,1), imagesc(x,y,C)
x = linspace(1, size(C, 2), numel(x)); % reverse only x
set(gca, 'XTick', x, 'XTickLabel', x)
subplot(2,2,2), imagesc(x,y,C2)
x = linspace(1, size(C, 2), numel(x)); % reverse back x
set(gca, 'XTick', x, 'XTickLabel', x) % reverse y
y = linspace(1, size(C, 1), numel(y));
set(gca, 'YTick', y, 'YTickLabel', flipud(y(:)))
subplot(2,2,3), imagesc(x,y,C3)
x = linspace(1, size(C, 2), numel(x)); % now both x,y reversed
set(gca, 'XTick', x, 'XTickLabel', x)
subplot(2,2,4), imagesc(x,y,C4)
Fig. 1 Output where axis stay untouched but images are flipped correctly,
Fig. 2 Output from attempt with moving xticks/yticks
Expected output:
Fig.1 (top-left) all correct in axes with figure
Fig.2 (top-right) y-axis correct but x-axis from 8 to 5
Fig.3 (lower-left) y-axis from 6 to 3 but x-axis correct
Fig.4 (lower-right) y-axis correct but x-axis from 3 to 6
Attempt 2
Code
% 1 start of vector 2 end of vector 3 length of vector
figure
subplot(2,2,1), imagesc(x,y,C)
x = linspace(size(C, 2), 1, numel(x)); % reverse only x
set(gca, 'XTick', x, 'XTickLabel', x)
subplot(2,2,2), imagesc(x,y,C2)
x = linspace(1, size(C, 2), numel(x)); % reverse back x
set(gca, 'XTick', x, 'XTickLabel', x)
y = linspace(size(C, 1), 1, numel(y)); % reverse y
set(gca, 'YTick', y, 'YTickLabel', flipud(y(:)))
subplot(2,2,3), imagesc(x,y,C3)
x = linspace(size(C, 2), 1, numel(x)); % now both x,y reversed
set(gca, 'XTick', x, 'XTickLabel', x)
y = linspace(1, size(C, 1), numel(y)); % reverse y
set(gca, 'YTick', y, 'YTickLabel', flipud(y(:)))
subplot(2,2,4), imagesc(x,y,C4)
Output
Error using matlab.graphics.axis.Axes/set
While setting the 'XTick' property of 'Axes':
Value must be a vector of type single or double whose values increase
Error in test_imagesc_subplot_figure (line 26)
set(gca, 'XTick', x, 'XTickLabel', x)
Eskapp's proposal
I do unsuccessfully the following but no change on Fig. 2; the first row of figures stay in the same increasing order of xaxis; I also tried instead of reverse - normal
figure
subplot(2,2,1), imagesc(x,y,C)
x = linspace(1, size(C, 2), numel(x)); % reverse only x
set(gca,'xdir','reverse')
subplot(2,2,2), imagesc(x,y,C2)
Output of Fig. 1 and Fig. 2 axis stay the same
Studying EBH's answer
Output in the y-axis label when using set(gca,'XTick',x,'XTickLabel',x, 'YTick',y,'YTickLabel',fliplr(y)) with variables y=linspace(0,180,181); x=0:0.5:10
Matlab: 2016a
OS: Debian 8.5 64 bit
Hardware: Asus Zenbook UX303UA
If I correctly understand your question, then this code does what you look for:
x = 5:8;
y = 3:6;
C = reshape(0:2:22,4,3).';
C2 = fliplr(C); % horizontal flip
C3 = flipud(C); % vertical flip
C4 = rot90(C,2); % horizontal+vertical flip
% the answer starts here:
subplot(2,2,1), imagesc(x,y,C)
set(gca,'XTick',x,'XTickLabel',x,...
'YTick',y,'YTickLabel',y)
subplot(2,2,2), imagesc(x,y,C2)
set(gca,'XTick',x,'XTickLabel',fliplr(x),...
'YTick',y,'YTickLabel',y)
subplot(2,2,3), imagesc(x,y,C3)
set(gca,'XTick',x,'XTickLabel',x,...
'YTick',y,'YTickLabel',fliplr(y))
subplot(2,2,4), imagesc(x,y,C4)
set(gca,'XTick',x,'XTickLabel',fliplr(x),...
'YTick',y,'YTickLabel',fliplr(y))
the result:
I changed you x and y from 2-element vectors, but it works also if:
x = [5 8];
y = [3 6];
BTW...
Instead of manipulating C and create C2...C4, you can just write:
subplot 221, imagesc(x,y,C)
subplot 222, imagesc(fliplr(x),y,C)
subplot 223, imagesc(x,fliplr(y),C)
subplot 224, imagesc(fliplr(x),fliplr(y),C)
and add the manipulation on the axis after each call to subplot like before.
Edit:
Using your sizes and limits of the vectors:
x = linspace(0,10,6);
y = linspace(0,180,19); % no need to plot each label
N = 3613;
C = diag(1:N)*ones(N)+rot90(diag(1:N)*ones(N)); % some arbitrary matrix
where all the rest of the code above remains the same, I get the following result:

Dlmwrite doesn't give any output to .xls

I have a Matlab file that reads a text file getting values for r, c and Beta. Using those 3 columns I want to combine this with a file in Matlab with airfoil coordinates which I eventually split up in slices (I want around 30 pieces) of X and Y coordinates.
The problem I'm facing is that the dlmwrite doesn't give any output files. The file did work before, but now I don't see any xls file appearing. I have looked at the dlmwrite specifically, but I can't find my mistake.
n is the number of slices I want to create, which is equal to the number of lines in the text file which contains r, c and Beta. The Z = ones(81,1) is the number of airfoil coordinates (X and Y together counts as 1)
clear all
close all
clc
%Create and output propeller geometry text files for solidworks
Propeller_Geometry = 'lllllaatsten.txt';
Airfoil_Geometry = 'as5048.txt'; %airfoil x_c, z_c
[r, c, beta] = textread(Propeller_Geometry) % (m, m, deg)
[x_c, z_c] = textread(Airfoil_Geometry); %(-, -)
c = c * 1000; % Chord Length (mm)
r = r * 1000; % Radius Length (mm)
beta = beta * pi / 180; % Angle from rotational velocity vector to lower blade edge (rad)
n = 50; % Number of slices
hold on
plot(x_c, z_c, '-b')
axis([0 1 -0.5 0.5])
xlabel('Unit Chord ( x/c)', 'fontsize', 14)
ylabel('Unit Height (z/c)', 'fontsize', 14)
title('TA22 Airfoil Geometry', 'fontsize', 14)
%Create dimensional slices
for i=1:n+1
x = x_c * c(i); % Dimensional Chord (mm)
y = z_c * c(i); % Dimensional Height (mm)
X = x * cos(-beta(i)) - y * sin(-beta(i)); % Rotated x-coordinate
Y = y * cos(-beta(i)) + x * sin(-beta(i)); % Rotated y-coordinate
Z = ones(81,1) * r(i);
P = horzcat(-X, Y, Z);
%dlmwrite(['Slice_' int2str(i)'.xls'], P, 'delimiter', '\t', 'precision', 8)
%dlmwrite(['stuk_' int2str(i) '.txt'], P, 'delimiter', '\t', 'precision', 8)
dlmwrite (['stuk_' int2str(i) '.xls'], P, '-append', 'delimiter', '\t', 'newline', 'pc')
plot3(Z, -X, Y); %cm
axis([0 50 -30 0 -7 1])
xlabel('Radius (mm)', 'fontsize', 18)
ylabel('Chord (mm)', 'fontsize', 18)
zlabel('Height (cm)', 'fontsize', 18)
title('Propeller geometry', 'fontsize', 18)
grid
end

3D double Array to RGB in MATLAB

I have 256 x 256 x 3 double Array. How to create (RGB) picture from it in Mat-lab. The values are like (3091, 986, 1003, 1699). Thanks in advance..
You can normalise the values in the matrix so that they lie between 0 and 1 and then use the command imshow:
// create a random example of a matrix
I = 4000*rand(256, 256, 3);
// normalise the values in I
for i = 1:3
I(:, :, i) = I(:, :, i)/max(max(I(:, :, i)));
end
// display as image
imshow(I, 'InitialMagnification', 'fit')