Creating a geoTIFF from an image in Matlab - matlab

I'm trying to create a geoTIFF file in Matlab from the attached png.
example image
I'm following the example provided in:
https://uk.mathworks.com/help/map/examples/exporting-images-and-raster-grids-to-geotiff.html
but need to create georeferencing information from scratch, so using makerefmat and worldfilewrite to acheive this. The code below does not cause a crash, but generates a TIFF that image readers seem to struggle with, so I assume I'm doing something wrong. There may also be some redundancy as I haven't worked with TIFF tags before. Any help appreciated!
% Load image without georeferencing
RGB = imread('uk_dT.png');
% Create worldfile for image. At present this is done by first creating a
% reference matrix, then using these values to generate a worldfile.
% Longitude spans -17:10 (west to east), latitude 63:47 (north to south)
lonmin = -17; lonmax = 10; latmin = 47; latmax = 63;
DX = (lonmax-lonmin)/(length(RGB(1,:,1))); DY = (latmin-latmax)/(length(RGB(:,1,1)));
R = makerefmat(lonmin, latmax, DX, DY);
worldfilewrite(R,'uk_dT.tfw');
% Read worldfile, create geotiff
REF = worldfileread('uk_dT.tfw','geographic',size(RGB));
geotiffwrite('uk_dT.tif',RGB,REF)

Out of interest, this code was improved for me on another forum. The result still doesn't open in some image viewers, but I think that's to do with the class of the data. As I'm writing for GIS software this solution works for me.
file = 'uk_dT.png' ;
[path,name,ext] = fileparts(file) ;
I = imread(file) ;
lonmin = -17; lonmax = 10; latmin = 47; latmax = 63;
% Write to geotiff
R = georasterref('RasterSize',size(I),'LatitudeLimits', [latmin,latmax],'LongitudeLimits',[lonmin,lonmax]);
tiffile = strcat(name,'.tif') ;
geotiffwrite(tiffile,I,R)

Related

Vectorization of MATLAB code to optimize speed

Hey fellow MATLAB users. The following code is meant to analyze motion in films. However, when I run the script on a film, it takes almost 14 hours for MATLAB to run the code. I have heard that you can optimize running speed by vectorizing your code; however, I have no idea how to go about this with the code below, since I am far from a programmer.
Can anyone help me out, or point me in the right direction?
Thanks a lot – the m.code is as follows:
%calculates correlations in sequences of film shots 22 May 2014
%t = input vector of initial frames of all shots in the film
prompt1 = 'movie file = ';
movieavi = input(prompt1,'s');
mov = VideoReader(movieavi);
nshots = length(t)-1;
for n = 1:nshots
first = t(n);
last = t(n+1)-2;
slength = last - first + 1;
tempcor = 0;
for k = 1:(slength-1)
im1 = read(mov,first+k-1); %read the image
im2 = read(mov,first+k+1);
im1 = rgb2gray(im1); %convert to grayscale
im2 = rgb2gray(im2);
tmp = corr2(im1,im2);
if(isnan(tmp) == 1)
tmp = .9999;
end
tempcor = tempcor + tmp;
end
dataout(n,3) = tempcor/(slength-1); %mean Lag 1 correlation within a shot
dataout(n,1) = uint32(first/100); %frame in hundreds. Can't export 6 digit integer
dataout(n,2) = mod(first,100); %modolus 100, to be combined with above
cycle = t(n)
end;
xlswrite('dataout.xls', dataout) %this file appears in matlab folder and must
save dataout; %the Matlab version of same

Saving a series of manually selected points

Just a quick question. I have generated a piece of code whereby I select the point of interest in every frame. However, the coordinates of the last selected point is the only one that is saved. Does anyone know how to set up the code such that all the points for each frame are saved for example in a text file with x position in column 1 and y position in column 2? Here is the code I have developed so far;
clear;
clc;
%% Video file information
obj = VideoReader('T9_720p_60p_60mm_f5.MOV');
%% Sampling rate
fps = get(obj, 'FrameRate');
dt = 1/fps;
%% Image Information
file_info = get(obj);
image_width = file_info.Width;
image_height = file_info.Height;
%%Desired image size
x_range = 1:image_height;
y_range = 1:image_width;
szx = length(x_range);
szy = length(y_range);
%%Image processing - Point selection
for n = 33:115
frame = read(obj,n);
imshow(frame);
hpoint = impoint(gca, []);
Position = getPosition(hpoint);
end
I just realized all I need was to add the following before the end of the loop
%%Save data
n = n-32;
data(n,:) = [Position];
end
Regards

Extracting feature points from flow lines and clustering them?

I'm trying to make a reliable passenger counting system using matlab, the camera will be fixed and above the door. I a able to get flow lines using Lucas Kanade optical flow, the lines represent the people's motion. I want to:
extract from these lines only the end points, if the line is long enough (the lines matrix contains all the points, even say a point on some random part of floor which will not have changed)
Cluster these 'good points' and get the centroids of the clustsers, representing people
Create bounding boxes of a fixed size on those cluster centers and send them to the multiple object KLT tracking program.
Would anyone happen to show me a good way to extract the points I want from the line matrix? My matlab syntax is atrocious and I'm running out of time to get this done, its for a uni project. Thanks in advance!
%example
videoReader = vision.VideoFileReader('5Converted.avi','ImageColorSpace','Intensity','VideoOutputDataType','uint8');
converter = vision.ImageDataTypeConverter;
opticalFlow = vision.OpticalFlow('ReferenceFrameDelay', 1);
opticalFlow.OutputValue = 'Horizontal and vertical components in complex form';
shapeInserter = vision.ShapeInserter('Shape','Lines','BorderColor','Custom', 'CustomBorderColor', 255);
videoPlayer = vision.VideoPlayer('Name','Motion Vector');
while ~isDone(videoReader)
frame = step(videoReader);
im = step(converter, frame);
of = step(opticalFlow, im);
[lines, trackedPoints] = getFlowLines(of, 20);
if ~isempty(lines)
out = step(shapeInserter, im, lines);
end
end
release(videoPlayer);
release(videoReader);
And this is the GetFLowLines Function (slightly modified version of an example):
> function [vel_Lines, allTrackedPoints] = getFlowLines(vel_Values,
> scaleFactor) %Modified function based on Matlab's
> 'videooptflowlines.m' helper function
>
> persistent first_time; persistent X; persistent Y; persistent RV;
> persistent CV; if isempty(first_time)
> first_time = 1;
> %% user may change the following three parameters
> borderOffset = 5;
> decimFactorRow = 5;
> decimFactorCol = 5;
> %%
> [R C] = size(vel_Values);
> RV = borderOffset:decimFactorRow:(R-borderOffset);
> CV = borderOffset:decimFactorCol:(C-borderOffset);
> [Y X] = meshgrid(CV,RV); end
>
> tmp = vel_Values(RV,CV); tmp = tmp.*scaleFactor; vel_Lines = [Y(:)
> X(:) Y(:)+real(tmp(:)) X(:)+imag(tmp(:))]; allTrackedPoints =
> [Y(:)+real(tmp(:)) X(:)+imag(tmp(:))];

Multipage Tiff write in MATLAB doesn't work

I'm reading in a Tiff using the below function, which works fine, but when I try to use my write function to write that same Tiff back to a different file, it's all 255's. Does anyone know how to fix this? Thanks, Alex.
function Y = tiff_read(name)
% tiff reader that works
info = imfinfo(name);
T = numel(info);
d1 = info(1).Height;
d2 = info(1).Width;
Y = zeros(d1,d2,T);
for t = 1:T
temp = imread(name, t, 'Info',info);
Y(:,:,t) = temp(1:end,1:end);
end
% Tiff writer that doesn't work
function tiff_write(Y,name)
% Y should be 3D, name should end in .tif
T = size(Y,3);
imwrite(Y(:,:,1),name);
for t = 2:T
imwrite(Y(:,:,t),name,'WriteMode','append');
end
Try using this line :
Y = zeros(d1,d2,T,'uint16');
instead of this one:
Y = zeros(d1,d2,T);
Your data are likely in uint16 format and when you export you clip the maximum value to 255 (uint8), which makes pixel with values greater than 255 (a LOT of them if your data is in uint16) appear white.
Otherwise you might want to use this line:
function tiff_write(Y,name)
% Y should be 3D, name should end in .tif
for t = 2:T
imwrite(Y(:,:,t)/255,name,'WriteMode','append');
end

Image template matching using correlation

I am developing a template matching program in MATLAB. The code runs well, and finds the closest result. My first question, in this code, I am using the function corr2(). I would like to try a version using the formula (I tried to upload a picture of but I need 10 reputations).
I understand the formula itself, but I am not sure what variables should I use to use it. For example, what is exactly the m and n mean in my images where can I get them? In another words, what does the formula take as inputs?
Second question is, when I run the code I have now, it takes long, is there any thing I can change to speed it up?
Original = imread('Red.jpg'); % Read original image
Template = imread('temp.png'); % Read template image
OriDu = im2double(Original); % convert original image
TempDu = im2double(Template); % convert template
OriH = size(Original, 1); %height of the Original image
OriW = size(Original, 2); %width of the Original image
OriD = size(Original, 3); %colour depth
TempH = size(Template, 1); %height of the Template image
TempW = size(Template, 2); %width of the Template image
TempD = size(Template, 3); %colour depth
TempDu = reshape(TempDu, TempH*TempW, 3);
corr = 0; % to check the best correlation found
%% two for loops to go through the original image.
for i = 1:OriH-TempH
for j = 1:OriW-TempW
% take a segment of the original image( same size as the template size)
segment = OriDu(i: (i - 1) + TempH, j: (j - 1) + TempW, :);
segment = reshape(segment, TempH*TempW, 3);
output = corr2(TempDu, segment);
if output > corr
corr = output;
x = i;
y = j;
end
end
end
figure;
subplot(1,2,1), imshow(Template), title('Template');
subplot(1,2,2), imshow(OriDu(x:x+TempH, y:y+TempW, :)),title('Segment of the similar part');