├── AreaCoincidence.m ├── BloodVessel.m ├── CCDistance.m ├── CMDistance.m ├── CMExample.m ├── Cell.m ├── CellDensity.m ├── CellHistogram.m ├── CellMinus.m ├── CentroidDetec.m ├── ColumnMatch.m ├── CombineVessel.m ├── DiameterHistogram.m ├── HistMatch.m ├── ManualSample.m ├── MeanBi.m ├── NIfTI_20140122 ├── FAQ.pdf ├── NIfTI_tools.pdf ├── UseANALYZE.pdf ├── affine.m ├── bipolar.m ├── bresenham_line3d.m ├── clip_nii.m ├── collapse_nii_scan.m ├── examples.txt ├── expand_nii_scan.m ├── extra_nii_hdr.m ├── flip_lr.m ├── get_nii_frame.m ├── license.txt ├── load_nii.m ├── load_nii_ext.m ├── load_nii_hdr.m ├── load_nii_img.m ├── load_untouch0_nii_hdr.m ├── load_untouch_header_only.m ├── load_untouch_nii.m ├── load_untouch_nii_hdr.m ├── load_untouch_nii_img.m ├── make_ana.m ├── make_nii.m ├── mat_into_hdr.m ├── pad_nii.m ├── reslice_nii.m ├── rri_file_menu.m ├── rri_orient.m ├── rri_orient_ui.m ├── rri_select_file.m ├── rri_xhair.m ├── rri_zoom_menu.m ├── save_nii.m ├── save_nii_ext.m ├── save_nii_hdr.m ├── save_untouch0_nii_hdr.m ├── save_untouch_header_only.m ├── save_untouch_nii.m ├── save_untouch_nii_hdr.m ├── save_untouch_slice.m ├── unxform_nii.m ├── verify_nii_ext.m ├── view_nii.m ├── view_nii_menu.m └── xform_nii.m ├── Pychange.m ├── README.md ├── SVM.m ├── TiffChange.m ├── TiffInput.m ├── VExample.m ├── VesselLineRead.m ├── VolPer.m ├── canny ├── Contents.m ├── canny.m ├── checkattributes.m ├── exindex.m ├── fractile.m ├── gradients_n.m ├── gsmoothn.m ├── hystThresh.m ├── license.txt └── nonmaxSuppress.m ├── cellErr.m ├── crop.m ├── diameter.m ├── expand.m ├── lenAnddia.m ├── manual.mat ├── matlab ├── getThemeThemes.csv ├── http_createHeader.m ├── http_paramsToString.m ├── samplecode.m └── urlread2.m ├── mydisplay.m ├── unet.m ├── v3d_matlab_io_basicdatatype ├── README.txt ├── basic_memory.cpp ├── basic_memory.h ├── checkMachineEndian.cpp ├── elementmexheader.h ├── loadRaw2Stack.m ├── loadRaw2Stack_c.cpp ├── loadRaw2Stack_c_2byte.cpp ├── load_v3d_apo_file.m ├── load_v3d_marker_file.m ├── load_v3d_neuron_file.m ├── load_v3d_pointcloud_file.m ├── load_v3d_raw_img_file.m ├── load_v3d_swc_file.m ├── loadfilelist.m ├── makeosmex_rawfile_io.m ├── mg_image_lib.cpp ├── mg_image_lib.h ├── mg_utilities.cpp ├── mg_utilities.h ├── saveStack2File_c.cpp ├── save_v3d_apo_file.m ├── save_v3d_marker_file.m ├── save_v3d_pointcloud_file.m ├── save_v3d_raw_img_file.m ├── save_v3d_swc_file.m ├── savefilelist.m ├── stackutil.cpp ├── stackutil.h └── trimmed_str.m ├── vessel.mat └── wrong.m /AreaCoincidence.m: -------------------------------------------------------------------------------- 1 | function [vPrecison,vRecall,vFmeasure] = AreaCoincidence(manualvessel48,vessel) 2 | temp = size(intersect(find(manualvessel48),find(vessel))); 3 | vRecall = temp/size(find(manualvessel48)); 4 | vPrecison = temp/size(find(vessel)); 5 | vFmeasure = 2*vPrecison*vRecall/(vRecall+vPrecison); 6 | 7 | -------------------------------------------------------------------------------- /BloodVessel.m: -------------------------------------------------------------------------------- 1 | function BiVessel = BloodVessel(data,thresh,size) 2 | 3 | %thresh = [0.01 0.5]; 4 | %size = 6; 5 | %figure;imshow(data(:,:,1),[]); 6 | %lower than low threshold means not edge, higher than high threshold means edge 7 | e = canny(data, [1 1 0], 'TMethod', 'relMax', 'TValue', thresh, 'SubPixel', true); 8 | %plot3(e.subpix{1}(e.edge), e.subpix{2}(e.edge), e.subpix{3}(e.edge), '.'); 9 | %figure;imshow(e.edge(:,:,1),[]); 10 | %imshow(e.subpix{1}(:,:,50)); 11 | shape = 'disk'; 12 | se = strel(shape,size); 13 | I = imdilate(e.edge,se); 14 | se = strel(shape,size); 15 | BiVessel = imerode(I,se); 16 | %figure;imshow(BiVessel(:,:,1)); 17 | -------------------------------------------------------------------------------- /CCDistance.m: -------------------------------------------------------------------------------- 1 | function ccdistance = CCDistance(cell, x, z) 2 | % expand and change 3 | 4 | h = z/x; 5 | squeeze = floor(h)/h; 6 | cell = expand(cell,h); 7 | Centroid = CentroidDetec(cell); 8 | Centroid = Centroid/squeeze; 9 | slice = length(Centroid(:,3)); 10 | distance = ones(2,slice); 11 | for i = 1:slice 12 | temp = Centroid; 13 | point = Centroid(i,:); 14 | temp(i,:) = []; 15 | [D,I] = pdist2(temp,point,'euclidean','Smallest',1);% I is indice position of vessel 16 | distance(1,i) = D; 17 | distance(2,i) = temp(I,3); 18 | end 19 | distance = distance'; 20 | xlswrite('ccdistance.xlsx',sortrows(distance,2)); 21 | ccdistance= mean(distance,1); 22 | ccdistance = ccdistance(1); 23 | %figure;hist(distance); 24 | -------------------------------------------------------------------------------- /CMDistance.m: -------------------------------------------------------------------------------- 1 | function [cmdistance3d,cmdistance2d] = CMDistance(cell, myelin, x, zxis) 2 | 3 | % expand and change 4 | h = zxis/x; 5 | squeeze = floor(h)/h; 6 | cell = expand(cell,h); 7 | myelin = expand(myelin,h); 8 | 9 | % points 10 | Centroid = CentroidDetec(cell); 11 | thresh = [0.01 0.5]; 12 | e = canny(double(myelin), [1 1 0], 'TMethod', 'relMax', 'TValue', thresh, 'SubPixel', true); 13 | temp = e.edge; 14 | [i,j,z]=ind2sub(size(temp),find(temp)); 15 | temp2 = [i,j,z]; 16 | 17 | Centroid = Centroid/squeeze; 18 | temp2 = temp2/squeeze; 19 | 20 | %distance 3d 21 | [D,I] = pdist2(temp2,Centroid,'euclidean','Smallest',1); 22 | % figure;hist(D,100) 23 | distancetemp = [D;Centroid(:,3)']; 24 | xlswrite('cmdistance3d.xlsx',distancetemp'); 25 | cmdistance3d = mean(distancetemp(:,1)); 26 | 27 | %distance 2d 28 | 29 | data3 = temp2; 30 | data3(:,3) = round(temp2(:,3)); 31 | CentroidData3 = Centroid; 32 | CentroidData3(:,3) = round(Centroid(:,3)); 33 | slice = length(CentroidData3(:,3)); 34 | distance = ones(slice,2); 35 | for i = 1:slice 36 | mytemp = data3(data3(:,3) == CentroidData3(i,3),:); 37 | [D,I] = pdist2(mytemp,CentroidData3(i,:),'euclidean','Smallest',1);% I is indice position of vessel 38 | if isempty(D) 39 | distance(i,1) = 0; 40 | else 41 | distance(i,1) = D; 42 | end 43 | distance(i,2) = CentroidData3(i,3); 44 | end 45 | cmdistance2d = mean(distance,1); 46 | cmdistance2d = cmdistance2d(1); 47 | %figure;hist(distance); 48 | xlswrite('cmdistance2d.xlsx',distance); 49 | -------------------------------------------------------------------------------- /CMExample.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/CMExample.m -------------------------------------------------------------------------------- /Cell.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/Cell.m -------------------------------------------------------------------------------- /CellDensity.m: -------------------------------------------------------------------------------- 1 | % compute the cell density around vessel 2 | function [distance2d, distance3d] = CellDensity(vessel,cell,h) 3 | CentroidData = CentroidDetec(cell); 4 | figure;scatter3(CentroidData(:,1),CentroidData(:,2),CentroidData(:,3));axis equal; 5 | data = vessel; 6 | figure;scatter3(data(1:end,1),data(1:end,2),data(1:end,3));axis equal 7 | 8 | %3d distance 9 | data2(:,3) = h*data(:,3); 10 | CentroidData2(:,3) = h*CentroidData(:,3); 11 | [D,I] = pdist2(data2,CentroidData2,'euclidean','Smallest',1);% I is indice position of vessel 12 | distance3d = mean(D); 13 | figure; plot(sort(D)); 14 | figure;hist(D,50); 15 | temp = round(max(D))+1; 16 | y = hist(D,temp); 17 | figure; plot(y); 18 | xlswrite('cvdistance3d.xlsx',D); 19 | % x = 1:temp; 20 | % cftool(x,y); 21 | 22 | %2d distance 23 | data3 = data; 24 | data3(:,3) = round(data(:,3)); 25 | CentroidData3 = CentroidData; 26 | CentroidData3(:,3) = round(CentroidData(:,3)); 27 | slice = length(CentroidData3(:,3)); 28 | distance = ones(slice,1); 29 | for i = 1:slice 30 | mytemp = data3(data3(:,3) == CentroidData3(i,3),:); 31 | [D,I] = pdist2(mytemp,CentroidData3(i,:),'euclidean','Smallest',1);% I is indice position of vessel 32 | if isempty(D) 33 | distance(i,1) = 0; 34 | else 35 | distance(i,1) = D; 36 | end 37 | end 38 | distance2d = mean(distance); 39 | figure;hist(distance); 40 | xlswrite('cvdistance2d.xlsx',distance); -------------------------------------------------------------------------------- /CellHistogram.m: -------------------------------------------------------------------------------- 1 | function cellHist = CellHistogram(cell,x,z) 2 | % 30nm in axis z is one section 3 | Centroid = CentroidDetec(cell); 4 | Centroid(:,3) = z*Centroid(:,3); 5 | temp = ceil(max(Centroid(:,3))); 6 | cellHist = hist(Centroid(:,3),temp); 7 | area = size(cell,1)*size(cell,2)*x^2; 8 | cellHist = 10^9*cellHist/area; % the number of cells in mm^3 9 | xlswrite('cellHist.xlsx',cellHist'); -------------------------------------------------------------------------------- /CellMinus.m: -------------------------------------------------------------------------------- 1 | function Crop = CellMinus(Crop,m) 2 | 3 | Crop1 = Crop(:,:,1:2:size(Crop,3)); 4 | Crop2 = Crop(:,:,2:2:size(Crop,3)); 5 | 6 | Crop3 = Crop2 - Crop1/m; 7 | 8 | % for i = 1:size(Crop3,3) 9 | % 10 | % end 11 | 12 | Crop = round(Crop3 - min(min(min(Crop3)))); 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /CentroidDetec.m: -------------------------------------------------------------------------------- 1 | function CentroidData = CentroidDetec(cell) 2 | cc=bwconncomp(cell); 3 | kk = struct2cell(regionprops(cc,'Centroid')); 4 | kk = kk'; 5 | CentroidData=cell2mat(kk); 6 | -------------------------------------------------------------------------------- /ColumnMatch.m: -------------------------------------------------------------------------------- 1 | function Col = ColumnMatch(outHist) 2 | % Match Columns to adjust the images 3 | Col = outHist; 4 | for j = 1:length(outHist(1,1,:)) 5 | Cell = outHist(:,:,j); 6 | curve = mean(Cell); 7 | total = mean(curve); 8 | newCell = Cell; 9 | for i = 1 : length(Cell(1,:)) 10 | newCell(:,i) = total*Cell(:,i)/curve(i); 11 | end 12 | Col(:,:,j) = newCell; 13 | end 14 | -------------------------------------------------------------------------------- /CombineVessel.m: -------------------------------------------------------------------------------- 1 | function VesselCenter = CombineVessel(vessel1, vessel2, template) 2 | [~, data1]=VesselLineRead(vessel1); 3 | [~, data2]=VesselLineRead(vessel2); 4 | cell = template; 5 | data2(:,1) = data2(:,1) + round(size(cell,2)/2); 6 | VesselCenter = cat(1,data1,data2); 7 | 8 | 9 | 10 | % switch nargin 11 | % case 2 12 | % c = a + b; 13 | % case 1 14 | % c = a + a; 15 | % otherwise 16 | % c = 0; 17 | % end -------------------------------------------------------------------------------- /DiameterHistogram.m: -------------------------------------------------------------------------------- 1 | function diaHist = DiameterHistogram(vessel1,vessel2) 2 | 3 | temp1 = load_v3d_swc_file(vessel1); 4 | temp2 = load_v3d_swc_file(vessel2); 5 | mat = 2*[temp1(:,6);temp2(:,6)]; 6 | diaHist = mean(mat); 7 | figure;hist(mat); -------------------------------------------------------------------------------- /HistMatch.m: -------------------------------------------------------------------------------- 1 | function outHist = HistMatch(Crop,num) 2 | % RawData is the data and num is the matched group 3 | % Because the maxmum of all slices is almost the same, so we use im2 = second/max(second(:)) 4 | 5 | RawData = Crop+1; 6 | outHist = ones(length(RawData(:,1,1)),length(RawData(1,:,1)),length(RawData(1,1,:))); 7 | second = RawData(:,:,num); 8 | maxs = max(second(:)); 9 | im2 = second/maxs; 10 | hist2 = imhist(im2,maxs); 11 | cdf2 = cumsum(hist2) / numel(im2); 12 | for i = 1:length(RawData(1,1,:)) 13 | first = RawData(:,:,i); 14 | maxf = max(first(:)); 15 | im1 = first/maxf; 16 | hist1 = imhist(im1,maxf); %// Compute histograms 17 | cdf1 = cumsum(hist1) / numel(im1); %// Compute CDFs 18 | newMax = max(maxf, maxs); 19 | M = zeros(newMax,1); %// Store mapping - Cast to uint8 to respect data type 20 | %// Compute the mapping 21 | for idx = 1 : maxf 22 | [~,ind] = min(abs(cdf1(idx) - cdf2)); % idx of cdf1 and ind of cdf2 23 | M(idx) = ind; 24 | end 25 | %// Now apply the mapping to get first image to make 26 | %// the image look like the distribution of the second image 27 | %first means changing first to second, out is the first data in second histogram 28 | 29 | out = M(first); % pay attention to this kind of transformation! excellent! 30 | 31 | outHist(:,:,i) = out; 32 | 33 | 34 | end 35 | -------------------------------------------------------------------------------- /ManualSample.m: -------------------------------------------------------------------------------- 1 | % small sample for manual verify 2 | len = 30; 3 | x = size(Crop,1); 4 | y = size(Crop,2); 5 | z = size(Crop,3); 6 | matR1 = zeros(len,len,len); 7 | matR2 = zeros(len,len,len); 8 | matA1 = Crop(round(x/4)-len/2:round(x/4)+len/2-1,round(y/4)-len/2:round(y/4)+len/2-1,round(z/4)-len/2:round(z/4)+len/2-1); 9 | matA2 = Crop(x-round(x/4)-len/2:x-round(x/4)+len/2-1,y-round(y/4)-len/2:y-round(y/4)+len/2-1,z-round(z/4)-len/2:z-round(z/4)+len/2-1); 10 | save_nii(make_nii(uint16(matR1)),'Bi.nii'); 11 | save_nii(make_nii(uint16(matR2)),'Bi.nii'); 12 | save_nii(make_nii(uint16(Crop)),'CellCropAll.nii'); -------------------------------------------------------------------------------- /MeanBi.m: -------------------------------------------------------------------------------- 1 | function Bi = MeanBi(Data,thresh,num,filter_size) 2 | % apply mean operation and then binarization 3 | %thresh = 0.2; % larger means less choosed region 4 | %num = 3; 5 | Bi = Data; 6 | for i = 1 : size(Data,3) 7 | I = Data(:,:,i)/max(max(Data(:,:,i))); 8 | for j = 1:num 9 | I = medfilt2(I,[filter_size,filter_size]); 10 | end 11 | I = im2bw(I,thresh); 12 | Bi(:,:,i) = I; 13 | end -------------------------------------------------------------------------------- /NIfTI_20140122/FAQ.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/NIfTI_20140122/FAQ.pdf -------------------------------------------------------------------------------- /NIfTI_20140122/NIfTI_tools.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/NIfTI_20140122/NIfTI_tools.pdf -------------------------------------------------------------------------------- /NIfTI_20140122/UseANALYZE.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/NIfTI_20140122/UseANALYZE.pdf -------------------------------------------------------------------------------- /NIfTI_20140122/bipolar.m: -------------------------------------------------------------------------------- 1 | %BIPOLAR returns an M-by-3 matrix containing a blue-red colormap, in 2 | % in which red stands for positive, blue stands for negative, 3 | % and white stands for 0. 4 | % 5 | % Usage: cmap = bipolar(M, lo, hi, contrast); or cmap = bipolar; 6 | % 7 | % cmap: output M-by-3 matrix for BIPOLAR colormap. 8 | % M: number of shades in the colormap. By default, it is the 9 | % same length as the current colormap. 10 | % lo: the lowest value to represent. 11 | % hi: the highest value to represent. 12 | % 13 | % Inspired from the LORETA PASCAL program: 14 | % http://www.unizh.ch/keyinst/NewLORETA 15 | % 16 | % jimmy@rotman-baycrest.on.ca 17 | % 18 | %---------------------------------------------------------------- 19 | function cmap = bipolar(M, lo, hi, contrast) 20 | 21 | if ~exist('contrast','var') 22 | contrast = 128; 23 | end 24 | 25 | if ~exist('lo','var') 26 | lo = -1; 27 | end 28 | 29 | if ~exist('hi','var') 30 | hi = 1; 31 | end 32 | 33 | if ~exist('M','var') 34 | cmap = colormap; 35 | M = size(cmap,1); 36 | end 37 | 38 | steepness = 10 ^ (1 - (contrast-1)/127); 39 | pos_infs = 1e-99; 40 | neg_infs = -1e-99; 41 | 42 | doubleredc = []; 43 | doublebluec = []; 44 | 45 | if lo >= 0 % all positive 46 | 47 | if lo == 0 48 | lo = pos_infs; 49 | end 50 | 51 | for i=linspace(hi/M, hi, M) 52 | t = exp(log(i/hi)*steepness); 53 | doubleredc = [doubleredc; [(1-t)+t,(1-t)+0,(1-t)+0]]; 54 | end 55 | 56 | cmap = doubleredc; 57 | 58 | elseif hi <= 0 % all negative 59 | 60 | if hi == 0 61 | hi = neg_infs; 62 | end 63 | 64 | for i=linspace(abs(lo)/M, abs(lo), M) 65 | t = exp(log(i/abs(lo))*steepness); 66 | doublebluec = [doublebluec; [(1-t)+0,(1-t)+0,(1-t)+t]]; 67 | end 68 | 69 | cmap = flipud(doublebluec); 70 | 71 | else 72 | 73 | if hi > abs(lo) 74 | maxc = hi; 75 | else 76 | maxc = abs(lo); 77 | end 78 | 79 | for i=linspace(maxc/M, hi, round(M*hi/(hi-lo))) 80 | t = exp(log(i/maxc)*steepness); 81 | doubleredc = [doubleredc; [(1-t)+t,(1-t)+0,(1-t)+0]]; 82 | end 83 | 84 | for i=linspace(maxc/M, abs(lo), round(M*abs(lo)/(hi-lo))) 85 | t = exp(log(i/maxc)*steepness); 86 | doublebluec = [doublebluec; [(1-t)+0,(1-t)+0,(1-t)+t]]; 87 | end 88 | 89 | cmap = [flipud(doublebluec); doubleredc]; 90 | 91 | end 92 | 93 | return; % bipolar 94 | 95 | -------------------------------------------------------------------------------- /NIfTI_20140122/bresenham_line3d.m: -------------------------------------------------------------------------------- 1 | % Generate X Y Z coordinates of a 3D Bresenham's line between 2 | % two given points. 3 | % 4 | % A very useful application of this algorithm can be found in the 5 | % implementation of Fischer's Bresenham interpolation method in my 6 | % another program that can rotate three dimensional image volume 7 | % with an affine matrix: 8 | % http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=21080 9 | % 10 | % Usage: [X Y Z] = bresenham_line3d(P1, P2, [precision]); 11 | % 12 | % P1 - vector for Point1, where P1 = [x1 y1 z1] 13 | % 14 | % P2 - vector for Point2, where P2 = [x2 y2 z2] 15 | % 16 | % precision (optional) - Although according to Bresenham's line 17 | % algorithm, point coordinates x1 y1 z1 and x2 y2 z2 should 18 | % be integer numbers, this program extends its limit to all 19 | % real numbers. If any of them are floating numbers, you 20 | % should specify how many digits of decimal that you would 21 | % like to preserve. Be aware that the length of output X Y 22 | % Z coordinates will increase in 10 times for each decimal 23 | % digit that you want to preserve. By default, the precision 24 | % is 0, which means that they will be rounded to the nearest 25 | % integer. 26 | % 27 | % X - a set of x coordinates on Bresenham's line 28 | % 29 | % Y - a set of y coordinates on Bresenham's line 30 | % 31 | % Z - a set of z coordinates on Bresenham's line 32 | % 33 | % Therefore, all points in XYZ set (i.e. P(i) = [X(i) Y(i) Z(i)]) 34 | % will constitute the Bresenham's line between P1 and P1. 35 | % 36 | % Example: 37 | % P1 = [12 37 6]; P2 = [46 3 35]; 38 | % [X Y Z] = bresenham_line3d(P1, P2); 39 | % figure; plot3(X,Y,Z,'s','markerface','b'); 40 | % 41 | % This program is ported to MATLAB from: 42 | % 43 | % B.Pendleton. line3d - 3D Bresenham's (a 3D line drawing algorithm) 44 | % ftp://ftp.isc.org/pub/usenet/comp.sources.unix/volume26/line3d, 1992 45 | % 46 | % Which is also referenced by: 47 | % 48 | % Fischer, J., A. del Rio (2004). A Fast Method for Applying Rigid 49 | % Transformations to Volume Data, WSCG2004 Conference. 50 | % http://wscg.zcu.cz/wscg2004/Papers_2004_Short/M19.pdf 51 | % 52 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 53 | % 54 | function [X,Y,Z] = bresenham_line3d(P1, P2, precision) 55 | 56 | if ~exist('precision','var') | isempty(precision) | round(precision) == 0 57 | precision = 0; 58 | P1 = round(P1); 59 | P2 = round(P2); 60 | else 61 | precision = round(precision); 62 | P1 = round(P1*(10^precision)); 63 | P2 = round(P2*(10^precision)); 64 | end 65 | 66 | d = max(abs(P2-P1)+1); 67 | X = zeros(1, d); 68 | Y = zeros(1, d); 69 | Z = zeros(1, d); 70 | 71 | x1 = P1(1); 72 | y1 = P1(2); 73 | z1 = P1(3); 74 | 75 | x2 = P2(1); 76 | y2 = P2(2); 77 | z2 = P2(3); 78 | 79 | dx = x2 - x1; 80 | dy = y2 - y1; 81 | dz = z2 - z1; 82 | 83 | ax = abs(dx)*2; 84 | ay = abs(dy)*2; 85 | az = abs(dz)*2; 86 | 87 | sx = sign(dx); 88 | sy = sign(dy); 89 | sz = sign(dz); 90 | 91 | x = x1; 92 | y = y1; 93 | z = z1; 94 | idx = 1; 95 | 96 | if(ax>=max(ay,az)) % x dominant 97 | yd = ay - ax/2; 98 | zd = az - ax/2; 99 | 100 | while(1) 101 | X(idx) = x; 102 | Y(idx) = y; 103 | Z(idx) = z; 104 | idx = idx + 1; 105 | 106 | if(x == x2) % end 107 | break; 108 | end 109 | 110 | if(yd >= 0) % move along y 111 | y = y + sy; 112 | yd = yd - ax; 113 | end 114 | 115 | if(zd >= 0) % move along z 116 | z = z + sz; 117 | zd = zd - ax; 118 | end 119 | 120 | x = x + sx; % move along x 121 | yd = yd + ay; 122 | zd = zd + az; 123 | end 124 | elseif(ay>=max(ax,az)) % y dominant 125 | xd = ax - ay/2; 126 | zd = az - ay/2; 127 | 128 | while(1) 129 | X(idx) = x; 130 | Y(idx) = y; 131 | Z(idx) = z; 132 | idx = idx + 1; 133 | 134 | if(y == y2) % end 135 | break; 136 | end 137 | 138 | if(xd >= 0) % move along x 139 | x = x + sx; 140 | xd = xd - ay; 141 | end 142 | 143 | if(zd >= 0) % move along z 144 | z = z + sz; 145 | zd = zd - ay; 146 | end 147 | 148 | y = y + sy; % move along y 149 | xd = xd + ax; 150 | zd = zd + az; 151 | end 152 | elseif(az>=max(ax,ay)) % z dominant 153 | xd = ax - az/2; 154 | yd = ay - az/2; 155 | 156 | while(1) 157 | X(idx) = x; 158 | Y(idx) = y; 159 | Z(idx) = z; 160 | idx = idx + 1; 161 | 162 | if(z == z2) % end 163 | break; 164 | end 165 | 166 | if(xd >= 0) % move along x 167 | x = x + sx; 168 | xd = xd - az; 169 | end 170 | 171 | if(yd >= 0) % move along y 172 | y = y + sy; 173 | yd = yd - az; 174 | end 175 | 176 | z = z + sz; % move along z 177 | xd = xd + ax; 178 | yd = yd + ay; 179 | end 180 | end 181 | 182 | if precision ~= 0 183 | X = X/(10^precision); 184 | Y = Y/(10^precision); 185 | Z = Z/(10^precision); 186 | end 187 | 188 | return; % bresenham_line3d 189 | 190 | -------------------------------------------------------------------------------- /NIfTI_20140122/clip_nii.m: -------------------------------------------------------------------------------- 1 | % CLIP_NII: Clip the NIfTI volume from any of the 6 sides 2 | % 3 | % Usage: nii = clip_nii(nii, [option]) 4 | % 5 | % Inputs: 6 | % 7 | % nii - NIfTI volume. 8 | % 9 | % option - struct instructing how many voxel to be cut from which side. 10 | % 11 | % option.cut_from_L = ( number of voxel ) 12 | % option.cut_from_R = ( number of voxel ) 13 | % option.cut_from_P = ( number of voxel ) 14 | % option.cut_from_A = ( number of voxel ) 15 | % option.cut_from_I = ( number of voxel ) 16 | % option.cut_from_S = ( number of voxel ) 17 | % 18 | % Options description in detail: 19 | % ============================== 20 | % 21 | % cut_from_L: Number of voxels from Left side will be clipped. 22 | % 23 | % cut_from_R: Number of voxels from Right side will be clipped. 24 | % 25 | % cut_from_P: Number of voxels from Posterior side will be clipped. 26 | % 27 | % cut_from_A: Number of voxels from Anterior side will be clipped. 28 | % 29 | % cut_from_I: Number of voxels from Inferior side will be clipped. 30 | % 31 | % cut_from_S: Number of voxels from Superior side will be clipped. 32 | % 33 | % NIfTI data format can be found on: http://nifti.nimh.nih.gov 34 | % 35 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 36 | % 37 | function nii = clip_nii(nii, opt) 38 | 39 | dims = abs(nii.hdr.dime.dim(2:4)); 40 | origin = abs(nii.hdr.hist.originator(1:3)); 41 | 42 | if isempty(origin) | all(origin == 0) % according to SPM 43 | origin = round((dims+1)/2); 44 | end 45 | 46 | cut_from_L = 0; 47 | cut_from_R = 0; 48 | cut_from_P = 0; 49 | cut_from_A = 0; 50 | cut_from_I = 0; 51 | cut_from_S = 0; 52 | 53 | if nargin > 1 & ~isempty(opt) 54 | if ~isstruct(opt) 55 | error('option argument should be a struct'); 56 | end 57 | 58 | if isfield(opt,'cut_from_L') 59 | cut_from_L = round(opt.cut_from_L); 60 | 61 | if cut_from_L >= origin(1) | cut_from_L < 0 62 | error('cut_from_L cannot be negative or cut beyond originator'); 63 | end 64 | end 65 | 66 | if isfield(opt,'cut_from_P') 67 | cut_from_P = round(opt.cut_from_P); 68 | 69 | if cut_from_P >= origin(2) | cut_from_P < 0 70 | error('cut_from_P cannot be negative or cut beyond originator'); 71 | end 72 | end 73 | 74 | if isfield(opt,'cut_from_I') 75 | cut_from_I = round(opt.cut_from_I); 76 | 77 | if cut_from_I >= origin(3) | cut_from_I < 0 78 | error('cut_from_I cannot be negative or cut beyond originator'); 79 | end 80 | end 81 | 82 | if isfield(opt,'cut_from_R') 83 | cut_from_R = round(opt.cut_from_R); 84 | 85 | if cut_from_R > dims(1)-origin(1) | cut_from_R < 0 86 | error('cut_from_R cannot be negative or cut beyond originator'); 87 | end 88 | end 89 | 90 | if isfield(opt,'cut_from_A') 91 | cut_from_A = round(opt.cut_from_A); 92 | 93 | if cut_from_A > dims(2)-origin(2) | cut_from_A < 0 94 | error('cut_from_A cannot be negative or cut beyond originator'); 95 | end 96 | end 97 | 98 | if isfield(opt,'cut_from_S') 99 | cut_from_S = round(opt.cut_from_S); 100 | 101 | if cut_from_S > dims(3)-origin(3) | cut_from_S < 0 102 | error('cut_from_S cannot be negative or cut beyond originator'); 103 | end 104 | end 105 | end 106 | 107 | nii = make_nii(nii.img( (cut_from_L+1) : (dims(1)-cut_from_R), ... 108 | (cut_from_P+1) : (dims(2)-cut_from_A), ... 109 | (cut_from_I+1) : (dims(3)-cut_from_S), ... 110 | :,:,:,:,:), nii.hdr.dime.pixdim(2:4), ... 111 | [origin(1)-cut_from_L origin(2)-cut_from_P origin(3)-cut_from_I], ... 112 | nii.hdr.dime.datatype, nii.hdr.hist.descrip); 113 | 114 | return; 115 | 116 | -------------------------------------------------------------------------------- /NIfTI_20140122/collapse_nii_scan.m: -------------------------------------------------------------------------------- 1 | % Collapse multiple single-scan NIFTI files into a multiple-scan NIFTI file 2 | % 3 | % Usage: collapse_nii_scan(scan_file_pattern, [collapsed_fileprefix], [scan_file_folder]) 4 | % 5 | % Here, scan_file_pattern should look like: 'myscan_0*.img' 6 | % If collapsed_fileprefix is omit, 'multi_scan' will be used 7 | % If scan_file_folder is omit, current file folder will be used 8 | % 9 | % The order of volumes in the collapsed file will be the order of 10 | % corresponding filenames for those selected scan files. 11 | % 12 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 13 | % 14 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 15 | % 16 | function collapse_nii_scan(scan_pattern, fileprefix, scan_path) 17 | 18 | if ~exist('fileprefix','var') 19 | fileprefix = 'multi_scan'; 20 | else 21 | [tmp fileprefix] = fileparts(fileprefix); 22 | end 23 | 24 | if ~exist('scan_path','var'), scan_path = pwd; end 25 | pnfn = fullfile(scan_path, scan_pattern); 26 | 27 | file_lst = dir(pnfn); 28 | flist = {file_lst.name}; 29 | flist = flist(:); 30 | filename = flist{1}; 31 | 32 | v = version; 33 | 34 | % Check file extension. If .gz, unpack it into temp folder 35 | % 36 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 37 | 38 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 39 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 40 | ~strcmp(filename(end-6:end), '.nii.gz') 41 | 42 | error('Please check filename.'); 43 | end 44 | 45 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 46 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 47 | else 48 | gzFile = 1; 49 | end 50 | else 51 | if ~strcmp(filename(end-3:end), '.img') & ... 52 | ~strcmp(filename(end-3:end), '.hdr') & ... 53 | ~strcmp(filename(end-3:end), '.nii') 54 | 55 | error('Please check filename.'); 56 | end 57 | end 58 | 59 | nii = load_untouch_nii(fullfile(scan_path,filename)); 60 | nii.hdr.dime.dim(5) = length(flist); 61 | 62 | if nii.hdr.dime.dim(1) < 4 63 | nii.hdr.dime.dim(1) = 4; 64 | end 65 | 66 | hdr = nii.hdr; 67 | filetype = nii.filetype; 68 | 69 | if isfield(nii,'ext') & ~isempty(nii.ext) 70 | ext = nii.ext; 71 | [ext, esize_total] = verify_nii_ext(ext); 72 | else 73 | ext = []; 74 | end 75 | 76 | switch double(hdr.dime.datatype), 77 | case 1, 78 | hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; 79 | case 2, 80 | hdr.dime.bitpix = int16(8 ); precision = 'uint8'; 81 | case 4, 82 | hdr.dime.bitpix = int16(16); precision = 'int16'; 83 | case 8, 84 | hdr.dime.bitpix = int16(32); precision = 'int32'; 85 | case 16, 86 | hdr.dime.bitpix = int16(32); precision = 'float32'; 87 | case 32, 88 | hdr.dime.bitpix = int16(64); precision = 'float32'; 89 | case 64, 90 | hdr.dime.bitpix = int16(64); precision = 'float64'; 91 | case 128, 92 | hdr.dime.bitpix = int16(24); precision = 'uint8'; 93 | case 256 94 | hdr.dime.bitpix = int16(8 ); precision = 'int8'; 95 | case 512 96 | hdr.dime.bitpix = int16(16); precision = 'uint16'; 97 | case 768 98 | hdr.dime.bitpix = int16(32); precision = 'uint32'; 99 | case 1024 100 | hdr.dime.bitpix = int16(64); precision = 'int64'; 101 | case 1280 102 | hdr.dime.bitpix = int16(64); precision = 'uint64'; 103 | case 1792, 104 | hdr.dime.bitpix = int16(128); precision = 'float64'; 105 | otherwise 106 | error('This datatype is not supported'); 107 | end 108 | 109 | if filetype == 2 110 | fid = fopen(sprintf('%s.nii',fileprefix),'w'); 111 | 112 | if fid < 0, 113 | msg = sprintf('Cannot open file %s.nii.',fileprefix); 114 | error(msg); 115 | end 116 | 117 | hdr.dime.vox_offset = 352; 118 | 119 | if ~isempty(ext) 120 | hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; 121 | end 122 | 123 | hdr.hist.magic = 'n+1'; 124 | save_untouch_nii_hdr(hdr, fid); 125 | 126 | if ~isempty(ext) 127 | save_nii_ext(ext, fid); 128 | end 129 | elseif filetype == 1 130 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 131 | 132 | if fid < 0, 133 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 134 | error(msg); 135 | end 136 | 137 | hdr.dime.vox_offset = 0; 138 | hdr.hist.magic = 'ni1'; 139 | save_untouch_nii_hdr(hdr, fid); 140 | 141 | if ~isempty(ext) 142 | save_nii_ext(ext, fid); 143 | end 144 | 145 | fclose(fid); 146 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 147 | else 148 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 149 | 150 | if fid < 0, 151 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 152 | error(msg); 153 | end 154 | 155 | save_untouch0_nii_hdr(hdr, fid); 156 | 157 | fclose(fid); 158 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 159 | end 160 | 161 | if filetype == 2 & isempty(ext) 162 | skip_bytes = double(hdr.dime.vox_offset) - 348; 163 | else 164 | skip_bytes = 0; 165 | end 166 | 167 | if skip_bytes 168 | fwrite(fid, zeros(1,skip_bytes), 'uint8'); 169 | end 170 | 171 | glmax = -inf; 172 | glmin = inf; 173 | 174 | for i = 1:length(flist) 175 | nii = load_untouch_nii(fullfile(scan_path,flist{i})); 176 | 177 | if double(hdr.dime.datatype) == 128 178 | 179 | % RGB planes are expected to be in the 4th dimension of nii.img 180 | % 181 | if(size(nii.img,4)~=3) 182 | error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 183 | end 184 | 185 | nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); 186 | end 187 | 188 | % For complex float32 or complex float64, voxel values 189 | % include [real, imag] 190 | % 191 | if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 192 | real_img = real(nii.img(:))'; 193 | nii.img = imag(nii.img(:))'; 194 | nii.img = [real_img; nii.img]; 195 | end 196 | 197 | if nii.hdr.dime.glmax > glmax 198 | glmax = nii.hdr.dime.glmax; 199 | end 200 | 201 | if nii.hdr.dime.glmin < glmin 202 | glmin = nii.hdr.dime.glmin; 203 | end 204 | 205 | fwrite(fid, nii.img, precision); 206 | end 207 | 208 | hdr.dime.glmax = round(glmax); 209 | hdr.dime.glmin = round(glmin); 210 | 211 | if filetype == 2 212 | fseek(fid, 140, 'bof'); 213 | fwrite(fid, hdr.dime.glmax, 'int32'); 214 | fwrite(fid, hdr.dime.glmin, 'int32'); 215 | elseif filetype == 1 216 | fid2 = fopen(sprintf('%s.hdr',fileprefix),'w'); 217 | 218 | if fid2 < 0, 219 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 220 | error(msg); 221 | end 222 | 223 | save_untouch_nii_hdr(hdr, fid2); 224 | 225 | if ~isempty(ext) 226 | save_nii_ext(ext, fid2); 227 | end 228 | 229 | fclose(fid2); 230 | else 231 | fid2 = fopen(sprintf('%s.hdr',fileprefix),'w'); 232 | 233 | if fid2 < 0, 234 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 235 | error(msg); 236 | end 237 | 238 | save_untouch0_nii_hdr(hdr, fid2); 239 | 240 | fclose(fid2); 241 | end 242 | 243 | fclose(fid); 244 | 245 | % gzip output file if requested 246 | % 247 | if exist('gzFile', 'var') 248 | if filetype == 1 249 | gzip([fileprefix, '.img']); 250 | delete([fileprefix, '.img']); 251 | gzip([fileprefix, '.hdr']); 252 | delete([fileprefix, '.hdr']); 253 | elseif filetype == 2 254 | gzip([fileprefix, '.nii']); 255 | delete([fileprefix, '.nii']); 256 | end; 257 | end; 258 | 259 | return; % collapse_nii_scan 260 | 261 | -------------------------------------------------------------------------------- /NIfTI_20140122/examples.txt: -------------------------------------------------------------------------------- 1 | 2 | - Examples to load, make and save a nii struct: 3 | 4 | To load Analyze data or NIFTI data to a structure: 5 | 6 | nii = load_nii(NIFTI_file_name, [img_idx], [old_RGB24]); 7 | 8 | img_idx is a numerical array of image indices along the temporal 9 | axis, which is only available in NIFTI data. After you specify 10 | img_idx, only those images indexed by img_idx will be loaded. If 11 | there is no img_idx or img_idx is empty, all available images 12 | will be loaded. 13 | 14 | For RGB image, most people use RGB triple sequentially for each 15 | voxel, like [R1 G1 B1 R2 G2 B2 ...]. However, some program like 16 | Analyze 6.0 developed by AnalyzeDirect uses old RGB24, in a way 17 | like [R1 R2 ... G1 G2 ... B1 B2 ...] for each slices. In this 18 | case, you can set old_RGB24 flag to 1 and load data correctly: 19 | 20 | nii = load_nii(NIFTI_file_name, [], 1); 21 | 22 | To get a total number of images along the temporal axis: 23 | 24 | num_scan = get_nii_frame(NIFTI_file_name); 25 | 26 | You can also load the header extension if it exists: 27 | 28 | nii.ext = load_nii_ext(NIFTI_file_name); 29 | 30 | You can just load the Analyze or NIFTI header: 31 | (header contains: hk, dime, and hist) 32 | 33 | hdr = load_nii_hdr(NIFTI_file_name); 34 | 35 | You can also save the structure to a new file: 36 | (header extension will be saved if there is nii.ext structure) 37 | 38 | save_nii(nii, NIFTI_file_name); 39 | 40 | To make the structure from any 3D (or 4D) data: 41 | 42 | img = rand(91,109,91); or 43 | img = rand(64,64,21,18); 44 | nii = make_nii(img [, voxel_size, origin, datatype] ); 45 | 46 | Use "help load_nii", "help save_nii", "help make_nii" etc. 47 | to get more detail information. 48 | 49 | 50 | - Examples to plot a nii struct: 51 | (More detail descriptions are available on top of "view_nii.m") 52 | 53 | Simple way to plot a nii struct: 54 | 55 | view_nii(nii); 56 | 57 | The default colormap will use the Gray if all data values are 58 | non-negative; otherwise, the default colormap will use BiPolar. 59 | You can choose other colormap, including customized colormap 60 | from panel. 61 | 62 | To imbed the plot into your existing figure: 63 | 64 | h = gcf; 65 | opt.command = 'init'; 66 | opt.setarea = [0.3 0.1 0.6 0.8]; 67 | view_nii(h, nii, opt); 68 | 69 | To add a colorbar: 70 | 71 | opt.usecolorbar = 1; 72 | view_nii(gcf, opt); 73 | 74 | Here, opt.command is implicitly set to 'update'. 75 | 76 | To display in real aspect ratio: 77 | 78 | opt.usestretch = 0; 79 | view_nii(gcf, opt); 80 | 81 | If you want the data value to be directly used as the index 82 | of colormap, instead of scale to the whole colormap: 83 | 84 | opt.useimagesc = 0; 85 | view_nii(gcf, opt); 86 | 87 | If you modified the data value without changing the dimension, 88 | voxel_size, and origin, you can update the display by: 89 | 90 | opt.command = 'updateimg'; 91 | view_nii(gcf, nii.img, opt); 92 | 93 | If the data is completely different, display can be updated by: 94 | 95 | opt.command = 'updatenii'; 96 | view_nii(gcf, nii, opt); 97 | 98 | This is an example to plot EEG source imaging on top of T1 background: 99 | 1. download overlay.zip and unzip it from: 100 | http://www.rotman-baycrest.on.ca/~jimmy/NIFTI/overlay.zip 101 | 2. T1 = load_nii('T1.nii'); 102 | 3. EEG = load_nii('EEG.nii'); 103 | 4. option.setvalue.idx = find(EEG.img); 104 | 5. option.setvalue.val = EEG.img(option.setvalue.idx); 105 | 6. option.useinterp = 1; 106 | 7. option.setviewpoint = [62 48 46]; 107 | 8. view_nii(T1, option); 108 | 109 | 110 | - Contrast and Brightness are available under Gray and Bipolar colormap: 111 | 112 | Increase contrast in Gray colormap will make high end values 113 | more distinguishable by sacrificing the low end values; The 114 | minimum contrast (default) will display the whole range. 115 | 116 | Increase or decrease contrast in BiPolar colormap will shift 117 | the distinguishable position for both positive and negative 118 | values. 119 | 120 | Increase or decrease brightness in Gray colormap will shift 121 | the distinguishable position. 122 | 123 | Increase or decrease brightness in BiPolar colormap will make 124 | both positive and negative values more distinguishable. 125 | 126 | 127 | - Required files: 128 | 129 | All files in this package. 130 | 131 | -------------------------------------------------------------------------------- /NIfTI_20140122/expand_nii_scan.m: -------------------------------------------------------------------------------- 1 | % Expand a multiple-scan NIFTI file into multiple single-scan NIFTI files 2 | % 3 | % Usage: expand_nii_scan(multi_scan_filename, [img_idx], [path_to_save]) 4 | % 5 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 6 | % 7 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 8 | % 9 | function expand_nii_scan(filename, img_idx, newpath) 10 | 11 | v = version; 12 | 13 | % Check file extension. If .gz, unpack it into temp folder 14 | % 15 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 16 | 17 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 18 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 19 | ~strcmp(filename(end-6:end), '.nii.gz') 20 | 21 | error('Please check filename.'); 22 | end 23 | 24 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 25 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 26 | else 27 | gzFile = 1; 28 | end 29 | end 30 | 31 | if ~exist('newpath','var') | isempty(newpath), newpath = pwd; end 32 | if ~exist('img_idx','var') | isempty(img_idx), img_idx = 1:get_nii_frame(filename); end 33 | 34 | for i=img_idx 35 | nii_i = load_untouch_nii(filename, i); 36 | 37 | fn = [nii_i.fileprefix '_' sprintf('%04d',i)]; 38 | pnfn = fullfile(newpath, fn); 39 | 40 | if exist('gzFile', 'var') 41 | pnfn = [pnfn '.nii.gz']; 42 | end 43 | 44 | save_untouch_nii(nii_i, pnfn); 45 | end 46 | 47 | return; % expand_nii_scan 48 | 49 | -------------------------------------------------------------------------------- /NIfTI_20140122/flip_lr.m: -------------------------------------------------------------------------------- 1 | % When you load any ANALYZE or NIfTI file with 'load_nii.m', and view 2 | % it with 'view_nii.m', you may find that the image is L-R flipped. 3 | % This is because of the confusion of radiological and neurological 4 | % convention in the medical image before NIfTI format is adopted. You 5 | % can find more details from: 6 | % 7 | % http://www.rotman-baycrest.on.ca/~jimmy/UseANALYZE.htm 8 | % 9 | % Sometime, people even want to convert RAS (standard orientation) back 10 | % to LAS orientation to satisfy the legend programs or processes. This 11 | % program is only written for those purpose. So PLEASE BE VERY CAUTIOUS 12 | % WHEN USING THIS 'FLIP_LR.M' PROGRAM. 13 | % 14 | % With 'flip_lr.m', you can convert any ANALYZE or NIfTI (no matter 15 | % 3D or 4D) file to a flipped NIfTI file. This is implemented simply 16 | % by flipping the affine matrix in the NIfTI header. Since the L-R 17 | % orientation is determined there, so the image will be flipped. 18 | % 19 | % Usage: flip_lr(original_fn, flipped_fn, [old_RGB],[tolerance],[preferredForm]) 20 | % 21 | % original_fn - filename of the original ANALYZE or NIfTI (3D or 4D) file 22 | % 23 | % flipped_fn - filename of the L-R flipped NIfTI file 24 | % 25 | % old_RGB (optional) - a scale number to tell difference of new RGB24 26 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 27 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 28 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 29 | % each slices. If the image that you view is garbled, try to set 30 | % old_RGB variable to 1 and try again, because it could be in 31 | % old RGB24. It will be set to 0, if it is default or empty. 32 | % 33 | % tolerance (optional) - distortion allowed for non-orthogonal rotation 34 | % or shearing in NIfTI affine matrix. It will be set to 0.1 (10%), 35 | % if it is default or empty. 36 | % 37 | % preferredForm (optional) - selects which transformation from voxels 38 | % to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate 39 | % "prefer sform or qform, but use others if preferred not present". 40 | % Upper case indicate the program is forced to use the specificied 41 | % tranform or fail loading. 'preferredForm' will be 's', if it is 42 | % default or empty. - Jeff Gunter 43 | % 44 | % Example: flip_lr('avg152T1_LR_nifti.nii', 'flipped_lr.nii'); 45 | % flip_lr('avg152T1_RL_nifti.nii', 'flipped_rl.nii'); 46 | % 47 | % You will find that 'avg152T1_LR_nifti.nii' and 'avg152T1_RL_nifti.nii' 48 | % are the same, and 'flipped_lr.nii' and 'flipped_rl.nii' are also the 49 | % the same, but they are L-R flipped from 'avg152T1_*'. 50 | % 51 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 52 | % 53 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 54 | % 55 | function flip_lr(original_fn, flipped_fn, old_RGB, tolerance, preferredForm) 56 | 57 | if ~exist('original_fn','var') | ~exist('flipped_fn','var') 58 | error('Usage: flip_lr(original_fn, flipped_fn, [old_RGB],[tolerance])'); 59 | end 60 | 61 | if ~exist('old_RGB','var') | isempty(old_RGB) 62 | old_RGB = 0; 63 | end 64 | 65 | if ~exist('tolerance','var') | isempty(tolerance) 66 | tolerance = 0.1; 67 | end 68 | 69 | if ~exist('preferredForm','var') | isempty(preferredForm) 70 | preferredForm= 's'; % Jeff 71 | end 72 | 73 | nii = load_nii(original_fn, [], [], [], [], old_RGB, tolerance, preferredForm); 74 | M = diag(nii.hdr.dime.pixdim(2:5)); 75 | M(1:3,4) = -M(1:3,1:3)*(nii.hdr.hist.originator(1:3)-1)'; 76 | M(1,:) = -1*M(1,:); 77 | nii.hdr.hist.sform_code = 1; 78 | nii.hdr.hist.srow_x = M(1,:); 79 | nii.hdr.hist.srow_y = M(2,:); 80 | nii.hdr.hist.srow_z = M(3,:); 81 | save_nii(nii, flipped_fn); 82 | 83 | return; % flip_lr 84 | 85 | -------------------------------------------------------------------------------- /NIfTI_20140122/get_nii_frame.m: -------------------------------------------------------------------------------- 1 | % Return time frame of a NIFTI dataset. Support both *.nii and 2 | % *.hdr/*.img file extension. If file extension is not provided, 3 | % *.hdr/*.img will be used as default. 4 | % 5 | % It is a lightweighted "load_nii_hdr", and is equivalent to 6 | % hdr.dime.dim(5) 7 | % 8 | % Usage: [ total_scan ] = get_nii_frame(filename) 9 | % 10 | % filename - NIFTI file name. 11 | % 12 | % Returned values: 13 | % 14 | % total_scan - total number of image scans for the time frame 15 | % 16 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 17 | % 18 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 19 | % 20 | function [ total_scan ] = get_nii_frame(filename) 21 | 22 | if ~exist('filename','var'), 23 | error('Usage: [ total_scan ] = get_nii_frame(filename)'); 24 | end 25 | 26 | v = version; 27 | 28 | % Check file extension. If .gz, unpack it into temp folder 29 | % 30 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 31 | 32 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 33 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 34 | ~strcmp(filename(end-6:end), '.nii.gz') 35 | 36 | error('Please check filename.'); 37 | end 38 | 39 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 40 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 41 | elseif strcmp(filename(end-6:end), '.img.gz') 42 | filename1 = filename; 43 | filename2 = filename; 44 | filename2(end-6:end) = ''; 45 | filename2 = [filename2, '.hdr.gz']; 46 | 47 | tmpDir = tempname; 48 | mkdir(tmpDir); 49 | gzFileName = filename; 50 | 51 | filename1 = gunzip(filename1, tmpDir); 52 | filename2 = gunzip(filename2, tmpDir); 53 | filename = char(filename1); % convert from cell to string 54 | elseif strcmp(filename(end-6:end), '.hdr.gz') 55 | filename1 = filename; 56 | filename2 = filename; 57 | filename2(end-6:end) = ''; 58 | filename2 = [filename2, '.img.gz']; 59 | 60 | tmpDir = tempname; 61 | mkdir(tmpDir); 62 | gzFileName = filename; 63 | 64 | filename1 = gunzip(filename1, tmpDir); 65 | filename2 = gunzip(filename2, tmpDir); 66 | filename = char(filename1); % convert from cell to string 67 | elseif strcmp(filename(end-6:end), '.nii.gz') 68 | tmpDir = tempname; 69 | mkdir(tmpDir); 70 | gzFileName = filename; 71 | filename = gunzip(filename, tmpDir); 72 | filename = char(filename); % convert from cell to string 73 | end 74 | end 75 | 76 | fileprefix = filename; 77 | machine = 'ieee-le'; 78 | new_ext = 0; 79 | 80 | if findstr('.nii',fileprefix) & strcmp(fileprefix(end-3:end), '.nii') 81 | new_ext = 1; 82 | fileprefix(end-3:end)=''; 83 | end 84 | 85 | if findstr('.hdr',fileprefix) & strcmp(fileprefix(end-3:end), '.hdr') 86 | fileprefix(end-3:end)=''; 87 | end 88 | 89 | if findstr('.img',fileprefix) & strcmp(fileprefix(end-3:end), '.img') 90 | fileprefix(end-3:end)=''; 91 | end 92 | 93 | if new_ext 94 | fn = sprintf('%s.nii',fileprefix); 95 | 96 | if ~exist(fn) 97 | msg = sprintf('Cannot find file "%s.nii".', fileprefix); 98 | error(msg); 99 | end 100 | else 101 | fn = sprintf('%s.hdr',fileprefix); 102 | 103 | if ~exist(fn) 104 | msg = sprintf('Cannot find file "%s.hdr".', fileprefix); 105 | error(msg); 106 | end 107 | end 108 | 109 | fid = fopen(fn,'r',machine); 110 | 111 | if fid < 0, 112 | msg = sprintf('Cannot open file %s.',fn); 113 | error(msg); 114 | else 115 | hdr = read_header(fid); 116 | fclose(fid); 117 | end 118 | 119 | if hdr.sizeof_hdr ~= 348 120 | % first try reading the opposite endian to 'machine' 121 | switch machine, 122 | case 'ieee-le', machine = 'ieee-be'; 123 | case 'ieee-be', machine = 'ieee-le'; 124 | end 125 | 126 | fid = fopen(fn,'r',machine); 127 | 128 | if fid < 0, 129 | msg = sprintf('Cannot open file %s.',fn); 130 | error(msg); 131 | else 132 | hdr = read_header(fid); 133 | fclose(fid); 134 | end 135 | end 136 | 137 | if hdr.sizeof_hdr ~= 348 138 | % Now throw an error 139 | msg = sprintf('File "%s" is corrupted.',fn); 140 | error(msg); 141 | end 142 | 143 | total_scan = hdr.dim(5); 144 | 145 | % Clean up after gunzip 146 | % 147 | if exist('gzFileName', 'var') 148 | rmdir(tmpDir,'s'); 149 | end 150 | 151 | return; % get_nii_frame 152 | 153 | 154 | %--------------------------------------------------------------------- 155 | function [ dsr ] = read_header(fid) 156 | 157 | fseek(fid,0,'bof'); 158 | dsr.sizeof_hdr = fread(fid,1,'int32')'; % should be 348! 159 | 160 | fseek(fid,40,'bof'); 161 | dsr.dim = fread(fid,8,'int16')'; 162 | 163 | return; % read_header 164 | 165 | -------------------------------------------------------------------------------- /NIfTI_20140122/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Jimmy Shen 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /NIfTI_20140122/load_nii.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI or ANALYZE dataset. Support both *.nii and *.hdr/*.img 2 | % file extension. If file extension is not provided, *.hdr/*.img will 3 | % be used as default. 4 | % 5 | % A subset of NIFTI transform is included. For non-orthogonal rotation, 6 | % shearing etc., please use 'reslice_nii.m' to reslice the NIFTI file. 7 | % It will not cause negative effect, as long as you remember not to do 8 | % slice time correction after reslicing the NIFTI file. Output variable 9 | % nii will be in RAS orientation, i.e. X axis from Left to Right, 10 | % Y axis from Posterior to Anterior, and Z axis from Inferior to 11 | % Superior. 12 | % 13 | % Usage: nii = load_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... 14 | % [dim7_idx], [old_RGB], [tolerance], [preferredForm]) 15 | % 16 | % filename - NIFTI or ANALYZE file name. 17 | % 18 | % img_idx (optional) - a numerical array of 4th dimension indices, 19 | % which is the indices of image scan volume. The number of images 20 | % scan volumes can be obtained from get_nii_frame.m, or simply 21 | % hdr.dime.dim(5). Only the specified volumes will be loaded. 22 | % All available image volumes will be loaded, if it is default or 23 | % empty. 24 | % 25 | % dim5_idx (optional) - a numerical array of 5th dimension indices. 26 | % Only the specified range will be loaded. All available range 27 | % will be loaded, if it is default or empty. 28 | % 29 | % dim6_idx (optional) - a numerical array of 6th dimension indices. 30 | % Only the specified range will be loaded. All available range 31 | % will be loaded, if it is default or empty. 32 | % 33 | % dim7_idx (optional) - a numerical array of 7th dimension indices. 34 | % Only the specified range will be loaded. All available range 35 | % will be loaded, if it is default or empty. 36 | % 37 | % old_RGB (optional) - a scale number to tell difference of new RGB24 38 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 39 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 40 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 41 | % each slices. If the image that you view is garbled, try to set 42 | % old_RGB variable to 1 and try again, because it could be in 43 | % old RGB24. It will be set to 0, if it is default or empty. 44 | % 45 | % tolerance (optional) - distortion allowed in the loaded image for any 46 | % non-orthogonal rotation or shearing of NIfTI affine matrix. If 47 | % you set 'tolerance' to 0, it means that you do not allow any 48 | % distortion. If you set 'tolerance' to 1, it means that you do 49 | % not care any distortion. The image will fail to be loaded if it 50 | % can not be tolerated. The tolerance will be set to 0.1 (10%), if 51 | % it is default or empty. 52 | % 53 | % preferredForm (optional) - selects which transformation from voxels 54 | % to RAS coordinates; values are s,q,S,Q. Lower case s,q indicate 55 | % "prefer sform or qform, but use others if preferred not present". 56 | % Upper case indicate the program is forced to use the specificied 57 | % tranform or fail loading. 'preferredForm' will be 's', if it is 58 | % default or empty. - Jeff Gunter 59 | % 60 | % Returned values: 61 | % 62 | % nii structure: 63 | % 64 | % hdr - struct with NIFTI header fields. 65 | % 66 | % filetype - Analyze format .hdr/.img (0); 67 | % NIFTI .hdr/.img (1); 68 | % NIFTI .nii (2) 69 | % 70 | % fileprefix - NIFTI filename without extension. 71 | % 72 | % machine - machine string variable. 73 | % 74 | % img - 3D (or 4D) matrix of NIFTI data. 75 | % 76 | % original - the original header before any affine transform. 77 | % 78 | % Part of this file is copied and modified from: 79 | % http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools 80 | % 81 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 82 | % 83 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 84 | % 85 | function nii = load_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... 86 | old_RGB, tolerance, preferredForm) 87 | 88 | if ~exist('filename','var') 89 | error('Usage: nii = load_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [tolerance], [preferredForm])'); 90 | end 91 | 92 | if ~exist('img_idx','var') | isempty(img_idx) 93 | img_idx = []; 94 | end 95 | 96 | if ~exist('dim5_idx','var') | isempty(dim5_idx) 97 | dim5_idx = []; 98 | end 99 | 100 | if ~exist('dim6_idx','var') | isempty(dim6_idx) 101 | dim6_idx = []; 102 | end 103 | 104 | if ~exist('dim7_idx','var') | isempty(dim7_idx) 105 | dim7_idx = []; 106 | end 107 | 108 | if ~exist('old_RGB','var') | isempty(old_RGB) 109 | old_RGB = 0; 110 | end 111 | 112 | if ~exist('tolerance','var') | isempty(tolerance) 113 | tolerance = 0.1; % 10 percent 114 | end 115 | 116 | if ~exist('preferredForm','var') | isempty(preferredForm) 117 | preferredForm= 's'; % Jeff 118 | end 119 | 120 | v = version; 121 | 122 | % Check file extension. If .gz, unpack it into temp folder 123 | % 124 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 125 | 126 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 127 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 128 | ~strcmp(filename(end-6:end), '.nii.gz') 129 | 130 | error('Please check filename.'); 131 | end 132 | 133 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 134 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 135 | elseif strcmp(filename(end-6:end), '.img.gz') 136 | filename1 = filename; 137 | filename2 = filename; 138 | filename2(end-6:end) = ''; 139 | filename2 = [filename2, '.hdr.gz']; 140 | 141 | tmpDir = tempname; 142 | mkdir(tmpDir); 143 | gzFileName = filename; 144 | 145 | filename1 = gunzip(filename1, tmpDir); 146 | filename2 = gunzip(filename2, tmpDir); 147 | filename = char(filename1); % convert from cell to string 148 | elseif strcmp(filename(end-6:end), '.hdr.gz') 149 | filename1 = filename; 150 | filename2 = filename; 151 | filename2(end-6:end) = ''; 152 | filename2 = [filename2, '.img.gz']; 153 | 154 | tmpDir = tempname; 155 | mkdir(tmpDir); 156 | gzFileName = filename; 157 | 158 | filename1 = gunzip(filename1, tmpDir); 159 | filename2 = gunzip(filename2, tmpDir); 160 | filename = char(filename1); % convert from cell to string 161 | elseif strcmp(filename(end-6:end), '.nii.gz') 162 | tmpDir = tempname; 163 | mkdir(tmpDir); 164 | gzFileName = filename; 165 | filename = gunzip(filename, tmpDir); 166 | filename = char(filename); % convert from cell to string 167 | end 168 | end 169 | 170 | % Read the dataset header 171 | % 172 | [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); 173 | 174 | % Read the header extension 175 | % 176 | % nii.ext = load_nii_ext(filename); 177 | 178 | % Read the dataset body 179 | % 180 | [nii.img,nii.hdr] = load_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... 181 | nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB); 182 | 183 | % Perform some of sform/qform transform 184 | % 185 | nii = xform_nii(nii, tolerance, preferredForm); 186 | 187 | % Clean up after gunzip 188 | % 189 | if exist('gzFileName', 'var') 190 | 191 | % fix fileprefix so it doesn't point to temp location 192 | % 193 | nii.fileprefix = gzFileName(1:end-7); 194 | rmdir(tmpDir,'s'); 195 | end 196 | 197 | return % load_nii 198 | 199 | -------------------------------------------------------------------------------- /NIfTI_20140122/load_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI header extension after its header is loaded using load_nii_hdr. 2 | % 3 | % Usage: ext = load_nii_ext(filename) 4 | % 5 | % filename - NIFTI file name. 6 | % 7 | % Returned values: 8 | % 9 | % ext - Structure of NIFTI header extension, which includes num_ext, 10 | % and all the extended header sections in the header extension. 11 | % Each extended header section will have its esize, ecode, and 12 | % edata, where edata can be plain text, xml, or any raw data 13 | % that was saved in the extended header section. 14 | % 15 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 16 | % 17 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 18 | % 19 | function ext = load_nii_ext(filename) 20 | 21 | if ~exist('filename','var'), 22 | error('Usage: ext = load_nii_ext(filename)'); 23 | end 24 | 25 | 26 | v = version; 27 | 28 | % Check file extension. If .gz, unpack it into temp folder 29 | % 30 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 31 | 32 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 33 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 34 | ~strcmp(filename(end-6:end), '.nii.gz') 35 | 36 | error('Please check filename.'); 37 | end 38 | 39 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 40 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 41 | elseif strcmp(filename(end-6:end), '.img.gz') 42 | filename1 = filename; 43 | filename2 = filename; 44 | filename2(end-6:end) = ''; 45 | filename2 = [filename2, '.hdr.gz']; 46 | 47 | tmpDir = tempname; 48 | mkdir(tmpDir); 49 | gzFileName = filename; 50 | 51 | filename1 = gunzip(filename1, tmpDir); 52 | filename2 = gunzip(filename2, tmpDir); 53 | filename = char(filename1); % convert from cell to string 54 | elseif strcmp(filename(end-6:end), '.hdr.gz') 55 | filename1 = filename; 56 | filename2 = filename; 57 | filename2(end-6:end) = ''; 58 | filename2 = [filename2, '.img.gz']; 59 | 60 | tmpDir = tempname; 61 | mkdir(tmpDir); 62 | gzFileName = filename; 63 | 64 | filename1 = gunzip(filename1, tmpDir); 65 | filename2 = gunzip(filename2, tmpDir); 66 | filename = char(filename1); % convert from cell to string 67 | elseif strcmp(filename(end-6:end), '.nii.gz') 68 | tmpDir = tempname; 69 | mkdir(tmpDir); 70 | gzFileName = filename; 71 | filename = gunzip(filename, tmpDir); 72 | filename = char(filename); % convert from cell to string 73 | end 74 | end 75 | 76 | machine = 'ieee-le'; 77 | new_ext = 0; 78 | 79 | if findstr('.nii',filename) & strcmp(filename(end-3:end), '.nii') 80 | new_ext = 1; 81 | filename(end-3:end)=''; 82 | end 83 | 84 | if findstr('.hdr',filename) & strcmp(filename(end-3:end), '.hdr') 85 | filename(end-3:end)=''; 86 | end 87 | 88 | if findstr('.img',filename) & strcmp(filename(end-3:end), '.img') 89 | filename(end-3:end)=''; 90 | end 91 | 92 | if new_ext 93 | fn = sprintf('%s.nii',filename); 94 | 95 | if ~exist(fn) 96 | msg = sprintf('Cannot find file "%s.nii".', filename); 97 | error(msg); 98 | end 99 | else 100 | fn = sprintf('%s.hdr',filename); 101 | 102 | if ~exist(fn) 103 | msg = sprintf('Cannot find file "%s.hdr".', filename); 104 | error(msg); 105 | end 106 | end 107 | 108 | fid = fopen(fn,'r',machine); 109 | vox_offset = 0; 110 | 111 | if fid < 0, 112 | msg = sprintf('Cannot open file %s.',fn); 113 | error(msg); 114 | else 115 | fseek(fid,0,'bof'); 116 | 117 | if fread(fid,1,'int32') == 348 118 | if new_ext 119 | fseek(fid,108,'bof'); 120 | vox_offset = fread(fid,1,'float32'); 121 | end 122 | 123 | ext = read_extension(fid, vox_offset); 124 | fclose(fid); 125 | else 126 | fclose(fid); 127 | 128 | % first try reading the opposite endian to 'machine' 129 | % 130 | switch machine, 131 | case 'ieee-le', machine = 'ieee-be'; 132 | case 'ieee-be', machine = 'ieee-le'; 133 | end 134 | 135 | fid = fopen(fn,'r',machine); 136 | 137 | if fid < 0, 138 | msg = sprintf('Cannot open file %s.',fn); 139 | error(msg); 140 | else 141 | fseek(fid,0,'bof'); 142 | 143 | if fread(fid,1,'int32') ~= 348 144 | 145 | % Now throw an error 146 | % 147 | msg = sprintf('File "%s" is corrupted.',fn); 148 | error(msg); 149 | end 150 | 151 | if new_ext 152 | fseek(fid,108,'bof'); 153 | vox_offset = fread(fid,1,'float32'); 154 | end 155 | 156 | ext = read_extension(fid, vox_offset); 157 | fclose(fid); 158 | end 159 | end 160 | end 161 | 162 | 163 | % Clean up after gunzip 164 | % 165 | if exist('gzFileName', 'var') 166 | rmdir(tmpDir,'s'); 167 | end 168 | 169 | 170 | return % load_nii_ext 171 | 172 | 173 | %--------------------------------------------------------------------- 174 | function ext = read_extension(fid, vox_offset) 175 | 176 | ext = []; 177 | 178 | if vox_offset 179 | end_of_ext = vox_offset; 180 | else 181 | fseek(fid, 0, 'eof'); 182 | end_of_ext = ftell(fid); 183 | end 184 | 185 | if end_of_ext > 352 186 | fseek(fid, 348, 'bof'); 187 | ext.extension = fread(fid,4)'; 188 | end 189 | 190 | if isempty(ext) | ext.extension(1) == 0 191 | ext = []; 192 | return; 193 | end 194 | 195 | i = 1; 196 | 197 | while(ftell(fid) < end_of_ext) 198 | ext.section(i).esize = fread(fid,1,'int32'); 199 | ext.section(i).ecode = fread(fid,1,'int32'); 200 | ext.section(i).edata = char(fread(fid,ext.section(i).esize-8)'); 201 | i = i + 1; 202 | end 203 | 204 | ext.num_ext = length(ext.section); 205 | 206 | return % read_extension 207 | 208 | -------------------------------------------------------------------------------- /NIfTI_20140122/load_untouch_header_only.m: -------------------------------------------------------------------------------- 1 | % Load NIfTI / Analyze header without applying any appropriate affine 2 | % geometric transform or voxel intensity scaling. It is equivalent to 3 | % hdr field when using load_untouch_nii to load dataset. Support both 4 | % *.nii and *.hdr file extension. If file extension is not provided, 5 | % *.hdr will be used as default. 6 | % 7 | % Usage: [header, ext, filetype, machine] = load_untouch_header_only(filename) 8 | % 9 | % filename - NIfTI / Analyze file name. 10 | % 11 | % Returned values: 12 | % 13 | % header - struct with NIfTI / Analyze header fields. 14 | % 15 | % ext - NIfTI extension if it is not empty. 16 | % 17 | % filetype - 0 for Analyze format (*.hdr/*.img); 18 | % 1 for NIFTI format in 2 files (*.hdr/*.img); 19 | % 2 for NIFTI format in 1 file (*.nii). 20 | % 21 | % machine - a string, see below for details. The default here is 'ieee-le'. 22 | % 23 | % 'native' or 'n' - local machine format - the default 24 | % 'ieee-le' or 'l' - IEEE floating point with little-endian 25 | % byte ordering 26 | % 'ieee-be' or 'b' - IEEE floating point with big-endian 27 | % byte ordering 28 | % 'vaxd' or 'd' - VAX D floating point and VAX ordering 29 | % 'vaxg' or 'g' - VAX G floating point and VAX ordering 30 | % 'cray' or 'c' - Cray floating point with big-endian 31 | % byte ordering 32 | % 'ieee-le.l64' or 'a' - IEEE floating point with little-endian 33 | % byte ordering and 64 bit long data type 34 | % 'ieee-be.l64' or 's' - IEEE floating point with big-endian byte 35 | % ordering and 64 bit long data type. 36 | % 37 | % Part of this file is copied and modified from: 38 | % http://www.mathworks.com/matlabcentral/fileexchange/1878-mri-analyze-tools 39 | % 40 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 41 | % 42 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 43 | % 44 | function [hdr, ext, filetype, machine] = load_untouch_header_only(filename) 45 | 46 | if ~exist('filename','var') 47 | error('Usage: [header, ext, filetype, machine] = load_untouch_header_only(filename)'); 48 | end 49 | 50 | 51 | v = version; 52 | 53 | % Check file extension. If .gz, unpack it into temp folder 54 | % 55 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 56 | 57 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 58 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 59 | ~strcmp(filename(end-6:end), '.nii.gz') 60 | 61 | error('Please check filename.'); 62 | end 63 | 64 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 65 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 66 | elseif strcmp(filename(end-6:end), '.img.gz') 67 | filename1 = filename; 68 | filename2 = filename; 69 | filename2(end-6:end) = ''; 70 | filename2 = [filename2, '.hdr.gz']; 71 | 72 | tmpDir = tempname; 73 | mkdir(tmpDir); 74 | gzFileName = filename; 75 | 76 | filename1 = gunzip(filename1, tmpDir); 77 | filename2 = gunzip(filename2, tmpDir); 78 | filename = char(filename1); % convert from cell to string 79 | elseif strcmp(filename(end-6:end), '.hdr.gz') 80 | filename1 = filename; 81 | filename2 = filename; 82 | filename2(end-6:end) = ''; 83 | filename2 = [filename2, '.img.gz']; 84 | 85 | tmpDir = tempname; 86 | mkdir(tmpDir); 87 | gzFileName = filename; 88 | 89 | filename1 = gunzip(filename1, tmpDir); 90 | filename2 = gunzip(filename2, tmpDir); 91 | filename = char(filename1); % convert from cell to string 92 | elseif strcmp(filename(end-6:end), '.nii.gz') 93 | tmpDir = tempname; 94 | mkdir(tmpDir); 95 | gzFileName = filename; 96 | filename = gunzip(filename, tmpDir); 97 | filename = char(filename); % convert from cell to string 98 | end 99 | end 100 | 101 | % Read the dataset header 102 | % 103 | [hdr, filetype, fileprefix, machine] = load_nii_hdr(filename); 104 | 105 | if filetype == 0 106 | hdr = load_untouch0_nii_hdr(fileprefix, machine); 107 | ext = []; 108 | else 109 | hdr = load_untouch_nii_hdr(fileprefix, machine, filetype); 110 | 111 | % Read the header extension 112 | % 113 | ext = load_nii_ext(filename); 114 | end 115 | 116 | % Set bitpix according to datatype 117 | % 118 | % /*Acceptable values for datatype are*/ 119 | % 120 | % 0 None (Unknown bit per voxel) % DT_NONE, DT_UNKNOWN 121 | % 1 Binary (ubit1, bitpix=1) % DT_BINARY 122 | % 2 Unsigned char (uchar or uint8, bitpix=8) % DT_UINT8, NIFTI_TYPE_UINT8 123 | % 4 Signed short (int16, bitpix=16) % DT_INT16, NIFTI_TYPE_INT16 124 | % 8 Signed integer (int32, bitpix=32) % DT_INT32, NIFTI_TYPE_INT32 125 | % 16 Floating point (single or float32, bitpix=32) % DT_FLOAT32, NIFTI_TYPE_FLOAT32 126 | % 32 Complex, 2 float32 (Use float32, bitpix=64) % DT_COMPLEX64, NIFTI_TYPE_COMPLEX64 127 | % 64 Double precision (double or float64, bitpix=64) % DT_FLOAT64, NIFTI_TYPE_FLOAT64 128 | % 128 uint8 RGB (Use uint8, bitpix=24) % DT_RGB24, NIFTI_TYPE_RGB24 129 | % 256 Signed char (schar or int8, bitpix=8) % DT_INT8, NIFTI_TYPE_INT8 130 | % 511 Single RGB (Use float32, bitpix=96) % DT_RGB96, NIFTI_TYPE_RGB96 131 | % 512 Unsigned short (uint16, bitpix=16) % DT_UNINT16, NIFTI_TYPE_UNINT16 132 | % 768 Unsigned integer (uint32, bitpix=32) % DT_UNINT32, NIFTI_TYPE_UNINT32 133 | % 1024 Signed long long (int64, bitpix=64) % DT_INT64, NIFTI_TYPE_INT64 134 | % 1280 Unsigned long long (uint64, bitpix=64) % DT_UINT64, NIFTI_TYPE_UINT64 135 | % 1536 Long double, float128 (Unsupported, bitpix=128) % DT_FLOAT128, NIFTI_TYPE_FLOAT128 136 | % 1792 Complex128, 2 float64 (Use float64, bitpix=128) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 137 | % 2048 Complex256, 2 float128 (Unsupported, bitpix=256) % DT_COMPLEX128, NIFTI_TYPE_COMPLEX128 138 | % 139 | switch hdr.dime.datatype 140 | case 1, 141 | hdr.dime.bitpix = 1; precision = 'ubit1'; 142 | case 2, 143 | hdr.dime.bitpix = 8; precision = 'uint8'; 144 | case 4, 145 | hdr.dime.bitpix = 16; precision = 'int16'; 146 | case 8, 147 | hdr.dime.bitpix = 32; precision = 'int32'; 148 | case 16, 149 | hdr.dime.bitpix = 32; precision = 'float32'; 150 | case 32, 151 | hdr.dime.bitpix = 64; precision = 'float32'; 152 | case 64, 153 | hdr.dime.bitpix = 64; precision = 'float64'; 154 | case 128, 155 | hdr.dime.bitpix = 24; precision = 'uint8'; 156 | case 256 157 | hdr.dime.bitpix = 8; precision = 'int8'; 158 | case 511 159 | hdr.dime.bitpix = 96; precision = 'float32'; 160 | case 512 161 | hdr.dime.bitpix = 16; precision = 'uint16'; 162 | case 768 163 | hdr.dime.bitpix = 32; precision = 'uint32'; 164 | case 1024 165 | hdr.dime.bitpix = 64; precision = 'int64'; 166 | case 1280 167 | hdr.dime.bitpix = 64; precision = 'uint64'; 168 | case 1792, 169 | hdr.dime.bitpix = 128; precision = 'float64'; 170 | otherwise 171 | error('This datatype is not supported'); 172 | end 173 | 174 | tmp = hdr.dime.dim(2:end); 175 | tmp(find(tmp < 1)) = 1; 176 | hdr.dime.dim(2:end) = tmp; 177 | 178 | 179 | % Clean up after gunzip 180 | % 181 | if exist('gzFileName', 'var') 182 | rmdir(tmpDir,'s'); 183 | end 184 | 185 | 186 | return % load_untouch_header_only 187 | 188 | -------------------------------------------------------------------------------- /NIfTI_20140122/load_untouch_nii.m: -------------------------------------------------------------------------------- 1 | % Load NIFTI or ANALYZE dataset, but not applying any appropriate affine 2 | % geometric transform or voxel intensity scaling. 3 | % 4 | % Although according to NIFTI website, all those header information are 5 | % supposed to be applied to the loaded NIFTI image, there are some 6 | % situations that people do want to leave the original NIFTI header and 7 | % data untouched. They will probably just use MATLAB to do certain image 8 | % processing regardless of image orientation, and to save data back with 9 | % the same NIfTI header. 10 | % 11 | % Since this program is only served for those situations, please use it 12 | % together with "save_untouch_nii.m", and do not use "save_nii.m" or 13 | % "view_nii.m" for the data that is loaded by "load_untouch_nii.m". For 14 | % normal situation, you should use "load_nii.m" instead. 15 | % 16 | % Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], ... 17 | % [dim7_idx], [old_RGB], [slice_idx]) 18 | % 19 | % filename - NIFTI or ANALYZE file name. 20 | % 21 | % img_idx (optional) - a numerical array of image volume indices. 22 | % Only the specified volumes will be loaded. All available image 23 | % volumes will be loaded, if it is default or empty. 24 | % 25 | % The number of images scans can be obtained from get_nii_frame.m, 26 | % or simply: hdr.dime.dim(5). 27 | % 28 | % dim5_idx (optional) - a numerical array of 5th dimension indices. 29 | % Only the specified range will be loaded. All available range 30 | % will be loaded, if it is default or empty. 31 | % 32 | % dim6_idx (optional) - a numerical array of 6th dimension indices. 33 | % Only the specified range will be loaded. All available range 34 | % will be loaded, if it is default or empty. 35 | % 36 | % dim7_idx (optional) - a numerical array of 7th dimension indices. 37 | % Only the specified range will be loaded. All available range 38 | % will be loaded, if it is default or empty. 39 | % 40 | % old_RGB (optional) - a scale number to tell difference of new RGB24 41 | % from old RGB24. New RGB24 uses RGB triple sequentially for each 42 | % voxel, like [R1 G1 B1 R2 G2 B2 ...]. Analyze 6.0 from AnalyzeDirect 43 | % uses old RGB24, in a way like [R1 R2 ... G1 G2 ... B1 B2 ...] for 44 | % each slices. If the image that you view is garbled, try to set 45 | % old_RGB variable to 1 and try again, because it could be in 46 | % old RGB24. It will be set to 0, if it is default or empty. 47 | % 48 | % slice_idx (optional) - a numerical array of image slice indices. 49 | % Only the specified slices will be loaded. All available image 50 | % slices will be loaded, if it is default or empty. 51 | % 52 | % Returned values: 53 | % 54 | % nii structure: 55 | % 56 | % hdr - struct with NIFTI header fields. 57 | % 58 | % filetype - Analyze format .hdr/.img (0); 59 | % NIFTI .hdr/.img (1); 60 | % NIFTI .nii (2) 61 | % 62 | % fileprefix - NIFTI filename without extension. 63 | % 64 | % machine - machine string variable. 65 | % 66 | % img - 3D (or 4D) matrix of NIFTI data. 67 | % 68 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 69 | % 70 | function nii = load_untouch_nii(filename, img_idx, dim5_idx, dim6_idx, dim7_idx, ... 71 | old_RGB, slice_idx) 72 | 73 | if ~exist('filename','var') 74 | error('Usage: nii = load_untouch_nii(filename, [img_idx], [dim5_idx], [dim6_idx], [dim7_idx], [old_RGB], [slice_idx])'); 75 | end 76 | 77 | if ~exist('img_idx','var') | isempty(img_idx) 78 | img_idx = []; 79 | end 80 | 81 | if ~exist('dim5_idx','var') | isempty(dim5_idx) 82 | dim5_idx = []; 83 | end 84 | 85 | if ~exist('dim6_idx','var') | isempty(dim6_idx) 86 | dim6_idx = []; 87 | end 88 | 89 | if ~exist('dim7_idx','var') | isempty(dim7_idx) 90 | dim7_idx = []; 91 | end 92 | 93 | if ~exist('old_RGB','var') | isempty(old_RGB) 94 | old_RGB = 0; 95 | end 96 | 97 | if ~exist('slice_idx','var') | isempty(slice_idx) 98 | slice_idx = []; 99 | end 100 | 101 | 102 | v = version; 103 | 104 | % Check file extension. If .gz, unpack it into temp folder 105 | % 106 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 107 | 108 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 109 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 110 | ~strcmp(filename(end-6:end), '.nii.gz') 111 | 112 | error('Please check filename.'); 113 | end 114 | 115 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 116 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 117 | elseif strcmp(filename(end-6:end), '.img.gz') 118 | filename1 = filename; 119 | filename2 = filename; 120 | filename2(end-6:end) = ''; 121 | filename2 = [filename2, '.hdr.gz']; 122 | 123 | tmpDir = tempname; 124 | mkdir(tmpDir); 125 | gzFileName = filename; 126 | 127 | filename1 = gunzip(filename1, tmpDir); 128 | filename2 = gunzip(filename2, tmpDir); 129 | filename = char(filename1); % convert from cell to string 130 | elseif strcmp(filename(end-6:end), '.hdr.gz') 131 | filename1 = filename; 132 | filename2 = filename; 133 | filename2(end-6:end) = ''; 134 | filename2 = [filename2, '.img.gz']; 135 | 136 | tmpDir = tempname; 137 | mkdir(tmpDir); 138 | gzFileName = filename; 139 | 140 | filename1 = gunzip(filename1, tmpDir); 141 | filename2 = gunzip(filename2, tmpDir); 142 | filename = char(filename1); % convert from cell to string 143 | elseif strcmp(filename(end-6:end), '.nii.gz') 144 | tmpDir = tempname; 145 | mkdir(tmpDir); 146 | gzFileName = filename; 147 | filename = gunzip(filename, tmpDir); 148 | filename = char(filename); % convert from cell to string 149 | end 150 | end 151 | 152 | % Read the dataset header 153 | % 154 | [nii.hdr,nii.filetype,nii.fileprefix,nii.machine] = load_nii_hdr(filename); 155 | 156 | if nii.filetype == 0 157 | nii.hdr = load_untouch0_nii_hdr(nii.fileprefix,nii.machine); 158 | nii.ext = []; 159 | else 160 | nii.hdr = load_untouch_nii_hdr(nii.fileprefix,nii.machine,nii.filetype); 161 | 162 | % Read the header extension 163 | % 164 | nii.ext = load_nii_ext(filename); 165 | end 166 | 167 | % Read the dataset body 168 | % 169 | [nii.img,nii.hdr] = load_untouch_nii_img(nii.hdr,nii.filetype,nii.fileprefix, ... 170 | nii.machine,img_idx,dim5_idx,dim6_idx,dim7_idx,old_RGB,slice_idx); 171 | 172 | % Perform some of sform/qform transform 173 | % 174 | % nii = xform_nii(nii, tolerance, preferredForm); 175 | 176 | nii.untouch = 1; 177 | 178 | 179 | % Clean up after gunzip 180 | % 181 | if exist('gzFileName', 'var') 182 | 183 | % fix fileprefix so it doesn't point to temp location 184 | % 185 | nii.fileprefix = gzFileName(1:end-7); 186 | rmdir(tmpDir,'s'); 187 | end 188 | 189 | 190 | return % load_untouch_nii 191 | 192 | -------------------------------------------------------------------------------- /NIfTI_20140122/make_ana.m: -------------------------------------------------------------------------------- 1 | % Make ANALYZE 7.5 data structure specified by a 3D or 4D matrix. 2 | % Optional parameters can also be included, such as: voxel_size, 3 | % origin, datatype, and description. 4 | % 5 | % Once the ANALYZE structure is made, it can be saved into ANALYZE 7.5 6 | % format data file using "save_untouch_nii" command (for more detail, 7 | % type: help save_untouch_nii). 8 | % 9 | % Usage: ana = make_ana(img, [voxel_size], [origin], [datatype], [description]) 10 | % 11 | % Where: 12 | % 13 | % img: a 3D matrix [x y z], or a 4D matrix with time 14 | % series [x y z t]. When image is in RGB format, 15 | % make sure that the size of 4th dimension is 16 | % always 3 (i.e. [R G B]). In that case, make 17 | % sure that you must specify RGB datatype to 128. 18 | % 19 | % voxel_size (optional): Voxel size in millimeter for each 20 | % dimension. Default is [1 1 1]. 21 | % 22 | % origin (optional): The AC origin. Default is [0 0 0]. 23 | % 24 | % datatype (optional): Storage data type: 25 | % 2 - uint8, 4 - int16, 8 - int32, 16 - float32, 26 | % 64 - float64, 128 - RGB24 27 | % Default will use the data type of 'img' matrix 28 | % For RGB image, you must specify it to 128. 29 | % 30 | % description (optional): Description of data. Default is ''. 31 | % 32 | % e.g.: 33 | % origin = [33 44 13]; datatype = 64; 34 | % ana = make_ana(img, [], origin, datatype); % default voxel_size 35 | % 36 | % ANALYZE 7.5 format: http://www.rotman-baycrest.on.ca/~jimmy/ANALYZE75.pdf 37 | % 38 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 39 | % 40 | function ana = make_ana(varargin) 41 | 42 | ana.img = varargin{1}; 43 | dims = size(ana.img); 44 | dims = [4 dims ones(1,8)]; 45 | dims = dims(1:8); 46 | 47 | voxel_size = [0 ones(1,3) zeros(1,4)]; 48 | origin = zeros(1,5); 49 | descrip = ''; 50 | 51 | switch class(ana.img) 52 | case 'uint8' 53 | datatype = 2; 54 | case 'int16' 55 | datatype = 4; 56 | case 'int32' 57 | datatype = 8; 58 | case 'single' 59 | datatype = 16; 60 | case 'double' 61 | datatype = 64; 62 | otherwise 63 | error('Datatype is not supported by make_ana.'); 64 | end 65 | 66 | if nargin > 1 & ~isempty(varargin{2}) 67 | voxel_size(2:4) = double(varargin{2}); 68 | end 69 | 70 | if nargin > 2 & ~isempty(varargin{3}) 71 | origin(1:3) = double(varargin{3}); 72 | end 73 | 74 | if nargin > 3 & ~isempty(varargin{4}) 75 | datatype = double(varargin{4}); 76 | 77 | if datatype == 128 | datatype == 511 78 | dims(5) = []; 79 | dims = [dims 1]; 80 | end 81 | end 82 | 83 | if nargin > 4 & ~isempty(varargin{5}) 84 | descrip = varargin{5}; 85 | end 86 | 87 | if ndims(ana.img) > 4 88 | error('NIfTI only allows a maximum of 4 Dimension matrix.'); 89 | end 90 | 91 | maxval = round(double(max(ana.img(:)))); 92 | minval = round(double(min(ana.img(:)))); 93 | 94 | ana.hdr = make_header(dims, voxel_size, origin, datatype, ... 95 | descrip, maxval, minval); 96 | ana.filetype = 0; 97 | ana.ext = []; 98 | ana.untouch = 1; 99 | 100 | switch ana.hdr.dime.datatype 101 | case 2 102 | ana.img = uint8(ana.img); 103 | case 4 104 | ana.img = int16(ana.img); 105 | case 8 106 | ana.img = int32(ana.img); 107 | case 16 108 | ana.img = single(ana.img); 109 | case 64 110 | ana.img = double(ana.img); 111 | case 128 112 | ana.img = uint8(ana.img); 113 | otherwise 114 | error('Datatype is not supported by make_ana.'); 115 | end 116 | 117 | return; % make_ana 118 | 119 | 120 | %--------------------------------------------------------------------- 121 | function hdr = make_header(dims, voxel_size, origin, datatype, ... 122 | descrip, maxval, minval) 123 | 124 | hdr.hk = header_key; 125 | hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); 126 | hdr.hist = data_history(origin, descrip); 127 | 128 | return; % make_header 129 | 130 | 131 | %--------------------------------------------------------------------- 132 | function hk = header_key 133 | 134 | hk.sizeof_hdr = 348; % must be 348! 135 | hk.data_type = ''; 136 | hk.db_name = ''; 137 | hk.extents = 0; 138 | hk.session_error = 0; 139 | hk.regular = 'r'; 140 | hk.hkey_un0 = '0'; 141 | 142 | return; % header_key 143 | 144 | 145 | %--------------------------------------------------------------------- 146 | function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) 147 | 148 | dime.dim = dims; 149 | dime.vox_units = 'mm'; 150 | dime.cal_units = ''; 151 | dime.unused1 = 0; 152 | dime.datatype = datatype; 153 | 154 | switch dime.datatype 155 | case 2, 156 | dime.bitpix = 8; precision = 'uint8'; 157 | case 4, 158 | dime.bitpix = 16; precision = 'int16'; 159 | case 8, 160 | dime.bitpix = 32; precision = 'int32'; 161 | case 16, 162 | dime.bitpix = 32; precision = 'float32'; 163 | case 64, 164 | dime.bitpix = 64; precision = 'float64'; 165 | case 128 166 | dime.bitpix = 24; precision = 'uint8'; 167 | otherwise 168 | error('Datatype is not supported by make_ana.'); 169 | end 170 | 171 | dime.dim_un0 = 0; 172 | dime.pixdim = voxel_size; 173 | dime.vox_offset = 0; 174 | dime.roi_scale = 1; 175 | dime.funused1 = 0; 176 | dime.funused2 = 0; 177 | dime.cal_max = 0; 178 | dime.cal_min = 0; 179 | dime.compressed = 0; 180 | dime.verified = 0; 181 | dime.glmax = maxval; 182 | dime.glmin = minval; 183 | 184 | return; % image_dimension 185 | 186 | 187 | %--------------------------------------------------------------------- 188 | function hist = data_history(origin, descrip) 189 | 190 | hist.descrip = descrip; 191 | hist.aux_file = 'none'; 192 | hist.orient = 0; 193 | hist.originator = origin; 194 | hist.generated = ''; 195 | hist.scannum = ''; 196 | hist.patient_id = ''; 197 | hist.exp_date = ''; 198 | hist.exp_time = ''; 199 | hist.hist_un0 = ''; 200 | hist.views = 0; 201 | hist.vols_added = 0; 202 | hist.start_field = 0; 203 | hist.field_skip = 0; 204 | hist.omax = 0; 205 | hist.omin = 0; 206 | hist.smax = 0; 207 | hist.smin = 0; 208 | 209 | return; % data_history 210 | 211 | -------------------------------------------------------------------------------- /NIfTI_20140122/make_nii.m: -------------------------------------------------------------------------------- 1 | % Make NIfTI structure specified by an N-D matrix. Usually, N is 3 for 2 | % 3D matrix [x y z], or 4 for 4D matrix with time series [x y z t]. 3 | % Optional parameters can also be included, such as: voxel_size, 4 | % origin, datatype, and description. 5 | % 6 | % Once the NIfTI structure is made, it can be saved into NIfTI file 7 | % using "save_nii" command (for more detail, type: help save_nii). 8 | % 9 | % Usage: nii = make_nii(img, [voxel_size], [origin], [datatype], [description]) 10 | % 11 | % Where: 12 | % 13 | % img: Usually, img is a 3D matrix [x y z], or a 4D 14 | % matrix with time series [x y z t]. However, 15 | % NIfTI allows a maximum of 7D matrix. When the 16 | % image is in RGB format, make sure that the size 17 | % of 4th dimension is always 3 (i.e. [R G B]). In 18 | % that case, make sure that you must specify RGB 19 | % datatype, which is either 128 or 511. 20 | % 21 | % voxel_size (optional): Voxel size in millimeter for each 22 | % dimension. Default is [1 1 1]. 23 | % 24 | % origin (optional): The AC origin. Default is [0 0 0]. 25 | % 26 | % datatype (optional): Storage data type: 27 | % 2 - uint8, 4 - int16, 8 - int32, 16 - float32, 28 | % 32 - complex64, 64 - float64, 128 - RGB24, 29 | % 256 - int8, 511 - RGB96, 512 - uint16, 30 | % 768 - uint32, 1792 - complex128 31 | % Default will use the data type of 'img' matrix 32 | % For RGB image, you must specify it to either 128 33 | % or 511. 34 | % 35 | % description (optional): Description of data. Default is ''. 36 | % 37 | % e.g.: 38 | % origin = [33 44 13]; datatype = 64; 39 | % nii = make_nii(img, [], origin, datatype); % default voxel_size 40 | % 41 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 42 | % 43 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 44 | % 45 | function nii = make_nii(varargin) 46 | 47 | nii.img = varargin{1}; 48 | dims = size(nii.img); 49 | dims = [length(dims) dims ones(1,8)]; 50 | dims = dims(1:8); 51 | 52 | voxel_size = [0 ones(1,7)]; 53 | origin = zeros(1,5); 54 | descrip = ''; 55 | 56 | switch class(nii.img) 57 | case 'uint8' 58 | datatype = 2; 59 | case 'int16' 60 | datatype = 4; 61 | case 'int32' 62 | datatype = 8; 63 | case 'single' 64 | if isreal(nii.img) 65 | datatype = 16; 66 | else 67 | datatype = 32; 68 | end 69 | case 'double' 70 | if isreal(nii.img) 71 | datatype = 64; 72 | else 73 | datatype = 1792; 74 | end 75 | case 'int8' 76 | datatype = 256; 77 | case 'uint16' 78 | datatype = 512; 79 | case 'uint32' 80 | datatype = 768; 81 | otherwise 82 | error('Datatype is not supported by make_nii.'); 83 | end 84 | 85 | if nargin > 1 & ~isempty(varargin{2}) 86 | voxel_size(2:4) = double(varargin{2}); 87 | end 88 | 89 | if nargin > 2 & ~isempty(varargin{3}) 90 | origin(1:3) = double(varargin{3}); 91 | end 92 | 93 | if nargin > 3 & ~isempty(varargin{4}) 94 | datatype = double(varargin{4}); 95 | 96 | if datatype == 128 | datatype == 511 97 | dims(5) = []; 98 | dims(1) = dims(1) - 1; 99 | dims = [dims 1]; 100 | end 101 | end 102 | 103 | if nargin > 4 & ~isempty(varargin{5}) 104 | descrip = varargin{5}; 105 | end 106 | 107 | if ndims(nii.img) > 7 108 | error('NIfTI only allows a maximum of 7 Dimension matrix.'); 109 | end 110 | 111 | maxval = round(double(max(nii.img(:)))); 112 | minval = round(double(min(nii.img(:)))); 113 | 114 | nii.hdr = make_header(dims, voxel_size, origin, datatype, ... 115 | descrip, maxval, minval); 116 | 117 | switch nii.hdr.dime.datatype 118 | case 2 119 | nii.img = uint8(nii.img); 120 | case 4 121 | nii.img = int16(nii.img); 122 | case 8 123 | nii.img = int32(nii.img); 124 | case 16 125 | nii.img = single(nii.img); 126 | case 32 127 | nii.img = single(nii.img); 128 | case 64 129 | nii.img = double(nii.img); 130 | case 128 131 | nii.img = uint8(nii.img); 132 | case 256 133 | nii.img = int8(nii.img); 134 | case 511 135 | img = double(nii.img(:)); 136 | img = single((img - min(img))/(max(img) - min(img))); 137 | nii.img = reshape(img, size(nii.img)); 138 | nii.hdr.dime.glmax = double(max(img)); 139 | nii.hdr.dime.glmin = double(min(img)); 140 | case 512 141 | nii.img = uint16(nii.img); 142 | case 768 143 | nii.img = uint32(nii.img); 144 | case 1792 145 | nii.img = double(nii.img); 146 | otherwise 147 | error('Datatype is not supported by make_nii.'); 148 | end 149 | 150 | return; % make_nii 151 | 152 | 153 | %--------------------------------------------------------------------- 154 | function hdr = make_header(dims, voxel_size, origin, datatype, ... 155 | descrip, maxval, minval) 156 | 157 | hdr.hk = header_key; 158 | hdr.dime = image_dimension(dims, voxel_size, datatype, maxval, minval); 159 | hdr.hist = data_history(origin, descrip); 160 | 161 | return; % make_header 162 | 163 | 164 | %--------------------------------------------------------------------- 165 | function hk = header_key 166 | 167 | hk.sizeof_hdr = 348; % must be 348! 168 | hk.data_type = ''; 169 | hk.db_name = ''; 170 | hk.extents = 0; 171 | hk.session_error = 0; 172 | hk.regular = 'r'; 173 | hk.dim_info = 0; 174 | 175 | return; % header_key 176 | 177 | 178 | %--------------------------------------------------------------------- 179 | function dime = image_dimension(dims, voxel_size, datatype, maxval, minval) 180 | 181 | dime.dim = dims; 182 | dime.intent_p1 = 0; 183 | dime.intent_p2 = 0; 184 | dime.intent_p3 = 0; 185 | dime.intent_code = 0; 186 | dime.datatype = datatype; 187 | 188 | switch dime.datatype 189 | case 2, 190 | dime.bitpix = 8; precision = 'uint8'; 191 | case 4, 192 | dime.bitpix = 16; precision = 'int16'; 193 | case 8, 194 | dime.bitpix = 32; precision = 'int32'; 195 | case 16, 196 | dime.bitpix = 32; precision = 'float32'; 197 | case 32, 198 | dime.bitpix = 64; precision = 'float32'; 199 | case 64, 200 | dime.bitpix = 64; precision = 'float64'; 201 | case 128 202 | dime.bitpix = 24; precision = 'uint8'; 203 | case 256 204 | dime.bitpix = 8; precision = 'int8'; 205 | case 511 206 | dime.bitpix = 96; precision = 'float32'; 207 | case 512 208 | dime.bitpix = 16; precision = 'uint16'; 209 | case 768 210 | dime.bitpix = 32; precision = 'uint32'; 211 | case 1792, 212 | dime.bitpix = 128; precision = 'float64'; 213 | otherwise 214 | error('Datatype is not supported by make_nii.'); 215 | end 216 | 217 | dime.slice_start = 0; 218 | dime.pixdim = voxel_size; 219 | dime.vox_offset = 0; 220 | dime.scl_slope = 0; 221 | dime.scl_inter = 0; 222 | dime.slice_end = 0; 223 | dime.slice_code = 0; 224 | dime.xyzt_units = 0; 225 | dime.cal_max = 0; 226 | dime.cal_min = 0; 227 | dime.slice_duration = 0; 228 | dime.toffset = 0; 229 | dime.glmax = maxval; 230 | dime.glmin = minval; 231 | 232 | return; % image_dimension 233 | 234 | 235 | %--------------------------------------------------------------------- 236 | function hist = data_history(origin, descrip) 237 | 238 | hist.descrip = descrip; 239 | hist.aux_file = 'none'; 240 | hist.qform_code = 0; 241 | hist.sform_code = 0; 242 | hist.quatern_b = 0; 243 | hist.quatern_c = 0; 244 | hist.quatern_d = 0; 245 | hist.qoffset_x = 0; 246 | hist.qoffset_y = 0; 247 | hist.qoffset_z = 0; 248 | hist.srow_x = zeros(1,4); 249 | hist.srow_y = zeros(1,4); 250 | hist.srow_z = zeros(1,4); 251 | hist.intent_name = ''; 252 | hist.magic = ''; 253 | hist.originator = origin; 254 | 255 | return; % data_history 256 | 257 | -------------------------------------------------------------------------------- /NIfTI_20140122/mat_into_hdr.m: -------------------------------------------------------------------------------- 1 | %MAT_INTO_HDR The old versions of SPM (any version before SPM5) store 2 | % an affine matrix of the SPM Reoriented image into a matlab file 3 | % (.mat extension). The file name of this SPM matlab file is the 4 | % same as the SPM Reoriented image file (.img/.hdr extension). 5 | % 6 | % This program will convert the ANALYZE 7.5 SPM Reoriented image 7 | % file into NIfTI format, and integrate the affine matrix in the 8 | % SPM matlab file into its header file (.hdr extension). 9 | % 10 | % WARNING: Before you run this program, please save the header 11 | % file (.hdr extension) into another file name or into another 12 | % folder location, because all header files (.hdr extension) 13 | % will be overwritten after they are converted into NIfTI 14 | % format. 15 | % 16 | % Usage: mat_into_hdr(filename); 17 | % 18 | % filename: file name(s) with .hdr or .mat file extension, like: 19 | % '*.hdr', or '*.mat', or a single .hdr or .mat file. 20 | % e.g. mat_into_hdr('T1.hdr') 21 | % mat_into_hdr('*.mat') 22 | % 23 | 24 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 25 | % 26 | %------------------------------------------------------------------------- 27 | function mat_into_hdr(files) 28 | 29 | pn = fileparts(files); 30 | file_lst = dir(files); 31 | file_lst = {file_lst.name}; 32 | file1 = file_lst{1}; 33 | [p n e]= fileparts(file1); 34 | 35 | for i=1:length(file_lst) 36 | [p n e]= fileparts(file_lst{i}); 37 | disp(['working on file ', num2str(i) ,' of ', num2str(length(file_lst)), ': ', n,e]); 38 | process=1; 39 | 40 | if isequal(e,'.hdr') 41 | mat=fullfile(pn, [n,'.mat']); 42 | hdr=fullfile(pn, file_lst{i}); 43 | 44 | if ~exist(mat,'file') 45 | warning(['Cannot find file "',mat , '". File "', n, e, '" will not be processed.']); 46 | process=0; 47 | end 48 | elseif isequal(e,'.mat') 49 | hdr=fullfile(pn, [n,'.hdr']); 50 | mat=fullfile(pn, file_lst{i}); 51 | 52 | if ~exist(hdr,'file') 53 | warning(['Can not find file "',hdr , '". File "', n, e, '" will not be processed.']); 54 | process=0; 55 | end 56 | else 57 | warning(['Input file must have .mat or .hdr extension. File "', n, e, '" will not be processed.']); 58 | process=0; 59 | end 60 | 61 | if process 62 | load(mat); 63 | R=M(1:3,1:3); 64 | T=M(1:3,4); 65 | T=R*ones(3,1)+T; 66 | M(1:3,4)=T; 67 | 68 | [h filetype fileprefix machine]=load_nii_hdr(hdr); 69 | h.hist.qform_code=0; 70 | h.hist.sform_code=1; 71 | h.hist.srow_x=M(1,:); 72 | h.hist.srow_y=M(2,:); 73 | h.hist.srow_z=M(3,:); 74 | h.hist.magic='ni1'; 75 | 76 | fid = fopen(hdr,'w',machine); 77 | save_nii_hdr(h,fid); 78 | fclose(fid); 79 | end 80 | end 81 | 82 | return; % mat_into_hdr 83 | 84 | -------------------------------------------------------------------------------- /NIfTI_20140122/pad_nii.m: -------------------------------------------------------------------------------- 1 | % PAD_NII: Pad the NIfTI volume from any of the 6 sides 2 | % 3 | % Usage: nii = pad_nii(nii, [option]) 4 | % 5 | % Inputs: 6 | % 7 | % nii - NIfTI volume. 8 | % 9 | % option - struct instructing how many voxel to be padded from which side. 10 | % 11 | % option.pad_from_L = ( number of voxel ) 12 | % option.pad_from_R = ( number of voxel ) 13 | % option.pad_from_P = ( number of voxel ) 14 | % option.pad_from_A = ( number of voxel ) 15 | % option.pad_from_I = ( number of voxel ) 16 | % option.pad_from_S = ( number of voxel ) 17 | % option.bg = [0] 18 | % 19 | % Options description in detail: 20 | % ============================== 21 | % 22 | % pad_from_L: Number of voxels from Left side will be padded. 23 | % 24 | % pad_from_R: Number of voxels from Right side will be padded. 25 | % 26 | % pad_from_P: Number of voxels from Posterior side will be padded. 27 | % 28 | % pad_from_A: Number of voxels from Anterior side will be padded. 29 | % 30 | % pad_from_I: Number of voxels from Inferior side will be padded. 31 | % 32 | % pad_from_S: Number of voxels from Superior side will be padded. 33 | % 34 | % bg: Background intensity, which is 0 by default. 35 | % 36 | % NIfTI data format can be found on: http://nifti.nimh.nih.gov 37 | % 38 | % - Jimmy Shen (jshen@research.baycrest.org) 39 | % 40 | function nii = pad_nii(nii, opt) 41 | 42 | dims = abs(nii.hdr.dime.dim(2:4)); 43 | origin = abs(nii.hdr.hist.originator(1:3)); 44 | 45 | if isempty(origin) | all(origin == 0) % according to SPM 46 | origin = round((dims+1)/2); 47 | end 48 | 49 | pad_from_L = 0; 50 | pad_from_R = 0; 51 | pad_from_P = 0; 52 | pad_from_A = 0; 53 | pad_from_I = 0; 54 | pad_from_S = 0; 55 | bg = 0; 56 | 57 | if nargin > 1 & ~isempty(opt) 58 | if ~isstruct(opt) 59 | error('option argument should be a struct'); 60 | end 61 | 62 | if isfield(opt,'pad_from_L') 63 | pad_from_L = round(opt.pad_from_L); 64 | 65 | if pad_from_L >= origin(1) | pad_from_L < 0 66 | error('pad_from_L cannot be negative'); 67 | end 68 | end 69 | 70 | if isfield(opt,'pad_from_P') 71 | pad_from_P = round(opt.pad_from_P); 72 | 73 | if pad_from_P >= origin(2) | pad_from_P < 0 74 | error('pad_from_P cannot be negative'); 75 | end 76 | end 77 | 78 | if isfield(opt,'pad_from_I') 79 | pad_from_I = round(opt.pad_from_I); 80 | 81 | if pad_from_I >= origin(3) | pad_from_I < 0 82 | error('pad_from_I cannot be negative'); 83 | end 84 | end 85 | 86 | if isfield(opt,'pad_from_R') 87 | pad_from_R = round(opt.pad_from_R); 88 | 89 | if pad_from_R > dims(1)-origin(1) | pad_from_R < 0 90 | error('pad_from_R cannot be negative'); 91 | end 92 | end 93 | 94 | if isfield(opt,'pad_from_A') 95 | pad_from_A = round(opt.pad_from_A); 96 | 97 | if pad_from_A > dims(2)-origin(2) | pad_from_A < 0 98 | error('pad_from_A cannot be negative'); 99 | end 100 | end 101 | 102 | if isfield(opt,'pad_from_S') 103 | pad_from_S = round(opt.pad_from_S); 104 | 105 | if pad_from_S > dims(3)-origin(3) | pad_from_S < 0 106 | error('pad_from_S cannot be negative'); 107 | end 108 | end 109 | 110 | if isfield(opt,'bg') 111 | bg = opt.bg; 112 | end 113 | end 114 | 115 | blk = bg * ones( pad_from_L, dims(2), dims(3) ); 116 | nii.img = cat(1, blk, nii.img); 117 | 118 | blk = bg * ones( pad_from_R, dims(2), dims(3) ); 119 | nii.img = cat(1, nii.img, blk); 120 | 121 | dims = size(nii.img); 122 | 123 | blk = bg * ones( dims(1), pad_from_P, dims(3) ); 124 | nii.img = cat(2, blk, nii.img); 125 | 126 | blk = bg * ones( dims(1), pad_from_A, dims(3) ); 127 | nii.img = cat(2, nii.img, blk); 128 | 129 | dims = size(nii.img); 130 | 131 | blk = bg * ones( dims(1), dims(2), pad_from_I ); 132 | nii.img = cat(3, blk, nii.img); 133 | 134 | blk = bg * ones( dims(1), dims(2), pad_from_S ); 135 | nii.img = cat(3, nii.img, blk); 136 | 137 | nii = make_nii(nii.img, nii.hdr.dime.pixdim(2:4), ... 138 | [origin(1)+pad_from_L origin(2)+pad_from_P origin(3)+pad_from_I], ... 139 | nii.hdr.dime.datatype, nii.hdr.hist.descrip); 140 | 141 | return; 142 | 143 | -------------------------------------------------------------------------------- /NIfTI_20140122/rri_file_menu.m: -------------------------------------------------------------------------------- 1 | % Imbed a file menu to any figure. If file menu exist, it will append 2 | % to the existing file menu. This file menu includes: Copy to clipboard, 3 | % print, save, close etc. 4 | % 5 | % Usage: rri_file_menu(fig); 6 | % 7 | % rri_file_menu(fig,0) means no 'Close' menu. 8 | % 9 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 10 | % 11 | %-------------------------------------------------------------------- 12 | 13 | function rri_file_menu(action, varargin) 14 | 15 | if isnumeric(action) 16 | fig = action; 17 | action = 'init'; 18 | end 19 | 20 | % clear the message line, 21 | % 22 | h = findobj(gcf,'Tag','MessageLine'); 23 | set(h,'String',''); 24 | 25 | if ~strcmp(action, 'init') 26 | set(gcbf, 'InvertHardcopy','off'); 27 | % set(gcbf, 'PaperPositionMode','auto'); 28 | end 29 | 30 | switch action 31 | case {'init'} 32 | if nargin > 1 33 | init(fig, 1); % no 'close' menu 34 | else 35 | init(fig, 0); 36 | end 37 | case {'print_fig'} 38 | printdlg(gcbf); 39 | case {'copy_fig'} 40 | copy_fig; 41 | case {'export_fig'} 42 | export_fig; 43 | end 44 | 45 | return % rri_file_menu 46 | 47 | 48 | %------------------------------------------------ 49 | % 50 | % Create (or append) File menu 51 | % 52 | function init(fig, no_close) 53 | 54 | % search for file menu 55 | % 56 | h_file = []; 57 | menuitems = findobj(fig, 'type', 'uimenu'); 58 | 59 | for i=1:length(menuitems) 60 | filelabel = get(menuitems(i),'label'); 61 | 62 | if strcmpi(strrep(filelabel, '&', ''), 'file') 63 | h_file = menuitems(i); 64 | break; 65 | end 66 | end 67 | 68 | set(fig, 'menubar', 'none'); 69 | 70 | if isempty(h_file) 71 | if isempty(menuitems) 72 | h_file = uimenu('parent', fig, 'label', 'File'); 73 | else 74 | h_file = uimenu('parent', fig, 'label', 'Copy Figure'); 75 | end 76 | 77 | h1 = uimenu('parent', h_file, ... 78 | 'callback','rri_file_menu(''copy_fig'');', ... 79 | 'label','Copy to Clipboard'); 80 | else 81 | h1 = uimenu('parent', h_file, ... 82 | 'callback','rri_file_menu(''copy_fig'');', ... 83 | 'separator','on', ... 84 | 'label','Copy to Clipboard'); 85 | end 86 | 87 | h2 = uimenu(h_file, ... 88 | 'callback','pagesetupdlg(gcbf);', ... 89 | 'label','Page Setup...'); 90 | 91 | h2 = uimenu(h_file, ... 92 | 'callback','printpreview(gcbf);', ... 93 | 'label','Print Preview...'); 94 | 95 | h2 = uimenu('parent', h_file, ... 96 | 'callback','printdlg(gcbf);', ... 97 | 'label','Print Figure ...'); 98 | 99 | h2 = uimenu('parent', h_file, ... 100 | 'callback','rri_file_menu(''export_fig'');', ... 101 | 'label','Save Figure ...'); 102 | 103 | arch = computer; 104 | if ~strcmpi(arch(1:2),'PC') 105 | set(h1, 'enable', 'off'); 106 | end 107 | 108 | if ~no_close 109 | h1 = uimenu('parent', h_file, ... 110 | 'callback','close(gcbf);', ... 111 | 'separator','on', ... 112 | 'label','Close'); 113 | end 114 | 115 | return; % init 116 | 117 | 118 | %------------------------------------------------ 119 | % 120 | % Copy to clipboard 121 | % 122 | function copy_fig 123 | 124 | arch = computer; 125 | if(~strcmpi(arch(1:2),'PC')) 126 | error('copy to clipboard can only be used under MS Windows'); 127 | return; 128 | end 129 | 130 | print -noui -dbitmap; 131 | 132 | return % copy_fig 133 | 134 | 135 | %------------------------------------------------ 136 | % 137 | % Save as an image file 138 | % 139 | function export_fig 140 | 141 | curr = pwd; 142 | if isempty(curr) 143 | curr = filesep; 144 | end 145 | 146 | [selected_file, selected_path] = rri_select_file(curr,'Save As'); 147 | 148 | if isempty(selected_file) | isempty(selected_path) 149 | return; 150 | end 151 | 152 | filename = [selected_path selected_file]; 153 | 154 | if(exist(filename,'file')==2) % file exist 155 | 156 | dlg_title = 'Confirm File Overwrite'; 157 | msg = ['File ',filename,' exist. Are you sure you want to overwrite it?']; 158 | response = questdlg(msg,dlg_title,'Yes','No','Yes'); 159 | 160 | if(strcmp(response,'No')) 161 | return; 162 | end 163 | 164 | end 165 | 166 | old_pointer = get(gcbf,'pointer'); 167 | set(gcbf,'pointer','watch'); 168 | 169 | try 170 | saveas(gcbf,filename); 171 | catch 172 | msg = 'ERROR: Cannot save file'; 173 | set(findobj(gcf,'Tag','MessageLine'),'String',msg); 174 | end 175 | 176 | set(gcbf,'pointer',old_pointer); 177 | 178 | return; % export_fig 179 | 180 | -------------------------------------------------------------------------------- /NIfTI_20140122/rri_orient.m: -------------------------------------------------------------------------------- 1 | % Convert image of different orientations to standard Analyze orientation 2 | % 3 | % Usage: nii = rri_orient(nii); 4 | 5 | % Jimmy Shen (jimmy@rotman-baycrest.on.ca), 26-APR-04 6 | %___________________________________________________________________ 7 | 8 | function [nii, orient, pattern] = rri_orient(nii, varargin) 9 | 10 | if nargin > 1 11 | pattern = varargin{1}; 12 | else 13 | pattern = []; 14 | end 15 | 16 | if(nargin > 2) 17 | orient = varargin{2}; 18 | if(length(find(orient>6)) || length(find(orient<1))) %value checking 19 | orient=[1 2 3]; %set to default if bogus values set 20 | end 21 | else 22 | orient = [1 2 3]; 23 | end 24 | 25 | 26 | dim = double(nii.hdr.dime.dim([2:4])); 27 | 28 | if ~isempty(pattern) & ~isequal(length(pattern), prod(dim)) 29 | return; 30 | end 31 | 32 | % get orient of the current image 33 | % 34 | if isequal(orient, [1 2 3]) 35 | orient = rri_orient_ui; 36 | pause(.1); 37 | end 38 | 39 | % no need for conversion 40 | % 41 | if isequal(orient, [1 2 3]) 42 | return; 43 | end 44 | 45 | if isempty(pattern) 46 | pattern = 1:prod(dim); 47 | end 48 | 49 | pattern = reshape(pattern, dim); 50 | img = nii.img; 51 | 52 | % calculate after flip orient 53 | % 54 | rot_orient = mod(orient + 2, 3) + 1; 55 | 56 | % do flip: 57 | % 58 | flip_orient = orient - rot_orient; 59 | 60 | for i = 1:3 61 | if flip_orient(i) 62 | pattern = flipdim(pattern, i); 63 | img = flipdim(img, i); 64 | end 65 | end 66 | 67 | % get index of orient (do inverse) 68 | % 69 | [tmp rot_orient] = sort(rot_orient); 70 | 71 | % do rotation: 72 | % 73 | pattern = permute(pattern, rot_orient); 74 | img = permute(img, [rot_orient 4 5 6]); 75 | 76 | % rotate resolution, or 'dim' 77 | % 78 | new_dim = nii.hdr.dime.dim([2:4]); 79 | new_dim = new_dim(rot_orient); 80 | nii.hdr.dime.dim([2:4]) = new_dim; 81 | 82 | % rotate voxel_size, or 'pixdim' 83 | % 84 | tmp = nii.hdr.dime.pixdim([2:4]); 85 | tmp = tmp(rot_orient); 86 | nii.hdr.dime.pixdim([2:4]) = tmp; 87 | 88 | % re-calculate originator 89 | % 90 | tmp = nii.hdr.hist.originator([1:3]); 91 | tmp = tmp(rot_orient); 92 | flip_orient = flip_orient(rot_orient); 93 | 94 | for i = 1:3 95 | if flip_orient(i) & ~isequal(double(tmp(i)), 0) 96 | tmp(i) = int16(double(new_dim(i)) - double(tmp(i)) + 1); 97 | end 98 | end 99 | 100 | nii.hdr.hist.originator([1:3]) = tmp; 101 | 102 | nii.img = img; 103 | pattern = pattern(:); 104 | 105 | return; % rri_orient 106 | 107 | -------------------------------------------------------------------------------- /NIfTI_20140122/rri_orient_ui.m: -------------------------------------------------------------------------------- 1 | % Return orientation of the current image: 2 | % orient is orientation 1x3 matrix, in that: 3 | % Three elements represent: [x y z] 4 | % Element value: 1 - Left to Right; 2 - Posterior to Anterior; 5 | % 3 - Inferior to Superior; 4 - Right to Left; 6 | % 5 - Anterior to Posterior; 6 - Superior to Inferior; 7 | % e.g.: 8 | % Standard RAS Orientation: [1 2 3] 9 | % Standard RHOS Orientation: [2 4 3] 10 | 11 | % Jimmy Shen (jimmy@rotman-baycrest.on.ca), 26-APR-04 12 | % 13 | function orient = rri_orient_ui(varargin) 14 | 15 | if nargin == 0 16 | init; 17 | orient_ui_fig = gcf; 18 | uiwait; % wait for user finish 19 | 20 | orient = getappdata(gcf, 'orient'); 21 | 22 | if isempty(orient) 23 | orient = [1 2 3]; 24 | end 25 | 26 | if ishandle(orient_ui_fig) 27 | close(gcf); 28 | end 29 | 30 | return; 31 | end 32 | 33 | action = varargin{1}; 34 | 35 | if strcmp(action, 'done') 36 | click_done; 37 | elseif strcmp(action, 'cancel') 38 | uiresume; 39 | end 40 | 41 | return; % rri_orient_ui 42 | 43 | 44 | %---------------------------------------------------------------------- 45 | function init 46 | 47 | save_setting_status = 'on'; 48 | rri_orient_pos = []; 49 | 50 | try 51 | load('pls_profile'); 52 | catch 53 | end 54 | 55 | try 56 | load('rri_pos_profile'); 57 | catch 58 | end 59 | 60 | if ~isempty(rri_orient_pos) & strcmp(save_setting_status,'on') 61 | 62 | pos = rri_orient_pos; 63 | 64 | else 65 | 66 | w = 0.35; 67 | h = 0.4; 68 | x = (1-w)/2; 69 | y = (1-h)/2; 70 | 71 | pos = [x y w h]; 72 | 73 | end 74 | 75 | handles.figure = figure('Color',[0.8 0.8 0.8], ... 76 | 'Units','normal', ... 77 | 'Name', 'Convert to standard RAS orientation', ... 78 | 'NumberTitle','off', ... 79 | 'MenuBar','none', ... 80 | 'Position',pos, ... 81 | 'WindowStyle', 'normal', ... 82 | 'ToolBar','none'); 83 | 84 | h0 = handles.figure; 85 | Font.FontUnits = 'point'; 86 | Font.FontSize = 12; 87 | 88 | margin = .1; 89 | line_num = 6; 90 | line_ht = (1 - margin*2) / line_num; 91 | 92 | x = margin; 93 | y = 1 - margin - line_ht; 94 | w = 1 - margin * 2; 95 | h = line_ht * .7; 96 | 97 | pos = [x y w h]; 98 | 99 | handles.Ttit = uicontrol('parent', h0, ... 100 | 'style','text', ... 101 | 'unit', 'normal', ... 102 | Font, ... 103 | 'Position',pos, ... 104 | 'HorizontalAlignment','left',... 105 | 'background', [0.8 0.8 0.8], ... 106 | 'string', 'Please input orientation of the current image:'); 107 | 108 | y = y - line_ht; 109 | w = .2; 110 | 111 | pos = [x y w h]; 112 | 113 | handles.Tx_orient = uicontrol('parent', h0, ... 114 | 'style','text', ... 115 | 'unit', 'normal', ... 116 | Font, ... 117 | 'Position',pos, ... 118 | 'HorizontalAlignment','left',... 119 | 'background', [0.8 0.8 0.8], ... 120 | 'string', 'X Axes:'); 121 | 122 | y = y - line_ht; 123 | 124 | pos = [x y w h]; 125 | 126 | handles.Ty_orient = uicontrol('parent', h0, ... 127 | 'style','text', ... 128 | 'unit', 'normal', ... 129 | Font, ... 130 | 'Position',pos, ... 131 | 'HorizontalAlignment','left',... 132 | 'background', [0.8 0.8 0.8], ... 133 | 'string', 'Y Axes:'); 134 | 135 | y = y - line_ht; 136 | 137 | pos = [x y w h]; 138 | 139 | handles.Tz_orient = uicontrol('parent', h0, ... 140 | 'style','text', ... 141 | 'unit', 'normal', ... 142 | Font, ... 143 | 'Position',pos, ... 144 | 'HorizontalAlignment','left',... 145 | 'background', [0.8 0.8 0.8], ... 146 | 'string', 'Z Axes:'); 147 | 148 | choice = { 'From Left to Right', 'From Posterior to Anterior', ... 149 | 'From Inferior to Superior', 'From Right to Left', ... 150 | 'From Anterior to Posterior', 'From Superior to Inferior' }; 151 | 152 | y = 1 - margin - line_ht; 153 | y = y - line_ht; 154 | w = 1 - margin - x - w; 155 | x = 1 - margin - w; 156 | 157 | pos = [x y w h]; 158 | 159 | handles.x_orient = uicontrol('parent', h0, ... 160 | 'style','popupmenu', ... 161 | 'unit', 'normal', ... 162 | Font, ... 163 | 'Position',pos, ... 164 | 'HorizontalAlignment','left',... 165 | 'string', choice, ... 166 | 'value', 1, ... 167 | 'background', [1 1 1]); 168 | 169 | y = y - line_ht; 170 | 171 | pos = [x y w h]; 172 | 173 | handles.y_orient = uicontrol('parent', h0, ... 174 | 'style','popupmenu', ... 175 | 'unit', 'normal', ... 176 | Font, ... 177 | 'Position',pos, ... 178 | 'HorizontalAlignment','left',... 179 | 'string', choice, ... 180 | 'value', 2, ... 181 | 'background', [1 1 1]); 182 | 183 | y = y - line_ht; 184 | 185 | pos = [x y w h]; 186 | 187 | handles.z_orient = uicontrol('parent', h0, ... 188 | 'style','popupmenu', ... 189 | 'unit', 'normal', ... 190 | Font, ... 191 | 'Position',pos, ... 192 | 'HorizontalAlignment','left',... 193 | 'string', choice, ... 194 | 'value', 3, ... 195 | 'background', [1 1 1]); 196 | 197 | x = margin; 198 | y = y - line_ht * 1.5; 199 | w = .3; 200 | 201 | pos = [x y w h]; 202 | 203 | handles.done = uicontrol('parent', h0, ... 204 | 'unit', 'normal', ... 205 | Font, ... 206 | 'Position',pos, ... 207 | 'HorizontalAlignment','center',... 208 | 'callback', 'rri_orient_ui(''done'');', ... 209 | 'string', 'Done'); 210 | 211 | x = 1 - margin - w; 212 | 213 | pos = [x y w h]; 214 | 215 | handles.cancel = uicontrol('parent', h0, ... 216 | 'unit', 'normal', ... 217 | Font, ... 218 | 'Position',pos, ... 219 | 'HorizontalAlignment','center',... 220 | 'callback', 'rri_orient_ui(''cancel'');', ... 221 | 'string', 'Cancel'); 222 | 223 | setappdata(h0, 'handles', handles); 224 | setappdata(h0, 'orient', [1 2 3]); 225 | 226 | return; % init 227 | 228 | 229 | %---------------------------------------------------------------------- 230 | function click_done 231 | 232 | handles = getappdata(gcf, 'handles'); 233 | 234 | x_orient = get(handles.x_orient, 'value'); 235 | y_orient = get(handles.y_orient, 'value'); 236 | z_orient = get(handles.z_orient, 'value'); 237 | 238 | orient = [x_orient y_orient z_orient]; 239 | test_orient = [orient, orient + 3]; 240 | test_orient = mod(test_orient, 3); 241 | 242 | if length(unique(test_orient)) ~= 3 243 | msgbox('Please don''t choose same or opposite direction','Error','modal'); 244 | return; 245 | end 246 | 247 | setappdata(gcf, 'orient', [x_orient y_orient z_orient]); 248 | uiresume; 249 | 250 | return; % click_done 251 | 252 | -------------------------------------------------------------------------------- /NIfTI_20140122/rri_xhair.m: -------------------------------------------------------------------------------- 1 | % rri_xhair: create a pair of full_cross_hair at point [x y] in 2 | % axes h_ax, and return xhair struct 3 | % 4 | % Usage: xhair = rri_xhair([x y], xhair, h_ax); 5 | % 6 | % If omit xhair, rri_xhair will create a pair of xhair; otherwise, 7 | % rri_xhair will update the xhair. If omit h_ax, current axes will 8 | % be used. 9 | % 10 | 11 | % 24-nov-2003 jimmy (jimmy@rotman-baycrest.on.ca) 12 | % 13 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 14 | 15 | function xhair = rri_xhair(varargin) 16 | 17 | if nargin == 0 18 | error('Please enter a point position as first argument'); 19 | return; 20 | end 21 | 22 | if nargin > 0 23 | p = varargin{1}; 24 | 25 | if ~isnumeric(p) | length(p) ~= 2 26 | error('Invalid point position'); 27 | return; 28 | else 29 | xhair = []; 30 | end 31 | end 32 | 33 | if nargin > 1 34 | xhair = varargin{2}; 35 | 36 | if ~isempty(xhair) 37 | if ~isstruct(xhair) 38 | error('Invalid xhair struct'); 39 | return; 40 | elseif ~isfield(xhair,'lx') | ~isfield(xhair,'ly') 41 | error('Invalid xhair struct'); 42 | return; 43 | elseif ~ishandle(xhair.lx) | ~ishandle(xhair.ly) 44 | error('Invalid xhair struct'); 45 | return; 46 | end 47 | 48 | lx = xhair.lx; 49 | ly = xhair.ly; 50 | else 51 | lx = []; 52 | ly = []; 53 | end 54 | end 55 | 56 | if nargin > 2 57 | h_ax = varargin{3}; 58 | 59 | if ~ishandle(h_ax) 60 | error('Invalid axes handle'); 61 | return; 62 | elseif ~strcmp(lower(get(h_ax,'type')), 'axes') 63 | error('Invalid axes handle'); 64 | return; 65 | end 66 | else 67 | h_ax = gca; 68 | end 69 | 70 | x_range = get(h_ax,'xlim'); 71 | y_range = get(h_ax,'ylim'); 72 | 73 | if ~isempty(xhair) 74 | set(lx, 'ydata', [p(2) p(2)]); 75 | set(ly, 'xdata', [p(1) p(1)]); 76 | set(h_ax, 'selected', 'on'); 77 | set(h_ax, 'selected', 'off'); 78 | else 79 | figure(get(h_ax,'parent')); 80 | axes(h_ax); 81 | 82 | xhair.lx = line('xdata', x_range, 'ydata', [p(2) p(2)], ... 83 | 'zdata', [11 11], 'color', [1 0 0], 'hittest', 'off'); 84 | xhair.ly = line('xdata', [p(1) p(1)], 'ydata', y_range, ... 85 | 'zdata', [11 11], 'color', [1 0 0], 'hittest', 'off'); 86 | end 87 | 88 | set(h_ax,'xlim',x_range); 89 | set(h_ax,'ylim',y_range); 90 | 91 | return; 92 | 93 | -------------------------------------------------------------------------------- /NIfTI_20140122/rri_zoom_menu.m: -------------------------------------------------------------------------------- 1 | % Imbed a zoom menu to any figure. 2 | % 3 | % Usage: rri_zoom_menu(fig); 4 | % 5 | 6 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 7 | % 8 | %-------------------------------------------------------------------- 9 | function menu_hdl = rri_zoom_menu(fig) 10 | 11 | if isnumeric(fig) 12 | menu_hdl = uimenu('Parent',fig, ... 13 | 'Label','Zoom on', ... 14 | 'Userdata', 1, ... 15 | 'Callback','rri_zoom_menu(''zoom'');'); 16 | 17 | return; 18 | end 19 | 20 | zoom_on_state = get(gcbo,'Userdata'); 21 | 22 | if (zoom_on_state == 1) 23 | zoom on; 24 | set(gcbo,'Userdata',0,'Label','Zoom off'); 25 | set(gcbf,'pointer','crosshair'); 26 | else 27 | zoom off; 28 | set(gcbo,'Userdata',1,'Label','Zoom on'); 29 | set(gcbf,'pointer','arrow'); 30 | end 31 | 32 | return % rri_zoom_menu 33 | 34 | -------------------------------------------------------------------------------- /NIfTI_20140122/save_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Save NIFTI header extension. 2 | % 3 | % Usage: save_nii_ext(ext, fid) 4 | % 5 | % ext - struct with NIFTI header extension fields. 6 | % 7 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 8 | % 9 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 10 | % 11 | function save_nii_ext(ext, fid) 12 | 13 | if ~exist('ext','var') | ~exist('fid','var') 14 | error('Usage: save_nii_ext(ext, fid)'); 15 | end 16 | 17 | if ~isfield(ext,'extension') | ~isfield(ext,'section') | ~isfield(ext,'num_ext') 18 | error('Wrong header extension'); 19 | end 20 | 21 | write_ext(ext, fid); 22 | 23 | return; % save_nii_ext 24 | 25 | 26 | %--------------------------------------------------------------------- 27 | function write_ext(ext, fid) 28 | 29 | fwrite(fid, ext.extension, 'uchar'); 30 | 31 | for i=1:ext.num_ext 32 | fwrite(fid, ext.section(i).esize, 'int32'); 33 | fwrite(fid, ext.section(i).ecode, 'int32'); 34 | fwrite(fid, ext.section(i).edata, 'uchar'); 35 | end 36 | 37 | return; % write_ext 38 | 39 | -------------------------------------------------------------------------------- /NIfTI_20140122/save_untouch_header_only.m: -------------------------------------------------------------------------------- 1 | % This function is only used to save Analyze or NIfTI header that is 2 | % ended with .hdr and loaded by load_untouch_header_only.m. If you 3 | % have NIfTI file that is ended with .nii and you want to change its 4 | % header only, you can use load_untouch_nii / save_untouch_nii pair. 5 | % 6 | % Usage: save_untouch_header_only(hdr, new_header_file_name) 7 | % 8 | % hdr - struct with NIfTI / Analyze header fields, which is obtained from: 9 | % hdr = load_untouch_header_only(original_header_file_name) 10 | % 11 | % new_header_file_name - NIfTI / Analyze header name ended with .hdr. 12 | % You can either copy original.img(.gz) to new.img(.gz) manually, 13 | % or simply input original.hdr(.gz) in save_untouch_header_only.m 14 | % to overwrite the original header. 15 | % 16 | % - Jimmy Shen (jshen@research.baycrest.org) 17 | % 18 | function save_untouch_header_only(hdr, filename) 19 | 20 | if ~exist('hdr','var') | isempty(hdr) | ~exist('filename','var') | isempty(filename) 21 | error('Usage: save_untouch_header_only(hdr, filename)'); 22 | end 23 | 24 | v = version; 25 | 26 | % Check file extension. If .gz, unpack it into temp folder 27 | % 28 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 29 | 30 | if ~strcmp(filename(end-6:end), '.hdr.gz') 31 | error('Please check filename.'); 32 | end 33 | 34 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 35 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 36 | else 37 | gzFile = 1; 38 | filename = filename(1:end-3); 39 | end 40 | end 41 | 42 | [p,f] = fileparts(filename); 43 | fileprefix = fullfile(p, f); 44 | 45 | write_hdr(hdr, fileprefix); 46 | 47 | % gzip output file if requested 48 | % 49 | if exist('gzFile', 'var') 50 | gzip([fileprefix, '.hdr']); 51 | delete([fileprefix, '.hdr']); 52 | end; 53 | 54 | return % save_untouch_header_only 55 | 56 | 57 | %----------------------------------------------------------------------------------- 58 | function write_hdr(hdr, fileprefix) 59 | 60 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 61 | 62 | if isfield(hdr.hist,'magic') 63 | save_untouch_nii_hdr(hdr, fid); 64 | else 65 | save_untouch0_nii_hdr(hdr, fid); 66 | end 67 | 68 | fclose(fid); 69 | 70 | return % write_hdr 71 | 72 | -------------------------------------------------------------------------------- /NIfTI_20140122/save_untouch_nii.m: -------------------------------------------------------------------------------- 1 | % Save NIFTI or ANALYZE dataset that is loaded by "load_untouch_nii.m". 2 | % The output image format and file extension will be the same as the 3 | % input one (NIFTI.nii, NIFTI.img or ANALYZE.img). Therefore, any file 4 | % extension that you specified will be ignored. 5 | % 6 | % Usage: save_untouch_nii(nii, filename) 7 | % 8 | % nii - nii structure that is loaded by "load_untouch_nii.m" 9 | % 10 | % filename - NIFTI or ANALYZE file name. 11 | % 12 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 13 | % 14 | function save_untouch_nii(nii, filename) 15 | 16 | if ~exist('nii','var') | isempty(nii) | ~isfield(nii,'hdr') | ... 17 | ~isfield(nii,'img') | ~exist('filename','var') | isempty(filename) 18 | 19 | error('Usage: save_untouch_nii(nii, filename)'); 20 | end 21 | 22 | if ~isfield(nii,'untouch') | nii.untouch == 0 23 | error('Usage: please use ''save_nii.m'' for the modified structure.'); 24 | end 25 | 26 | if isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'ni1') 27 | filetype = 1; 28 | elseif isfield(nii.hdr.hist,'magic') & strcmp(nii.hdr.hist.magic(1:3),'n+1') 29 | filetype = 2; 30 | else 31 | filetype = 0; 32 | end 33 | 34 | v = version; 35 | 36 | % Check file extension. If .gz, unpack it into temp folder 37 | % 38 | if length(filename) > 2 & strcmp(filename(end-2:end), '.gz') 39 | 40 | if ~strcmp(filename(end-6:end), '.img.gz') & ... 41 | ~strcmp(filename(end-6:end), '.hdr.gz') & ... 42 | ~strcmp(filename(end-6:end), '.nii.gz') 43 | 44 | error('Please check filename.'); 45 | end 46 | 47 | if str2num(v(1:3)) < 7.1 | ~usejava('jvm') 48 | error('Please use MATLAB 7.1 (with java) and above, or run gunzip outside MATLAB.'); 49 | else 50 | gzFile = 1; 51 | filename = filename(1:end-3); 52 | end 53 | end 54 | 55 | [p,f] = fileparts(filename); 56 | fileprefix = fullfile(p, f); 57 | 58 | write_nii(nii, filetype, fileprefix); 59 | 60 | % gzip output file if requested 61 | % 62 | if exist('gzFile', 'var') 63 | if filetype == 1 64 | gzip([fileprefix, '.img']); 65 | delete([fileprefix, '.img']); 66 | gzip([fileprefix, '.hdr']); 67 | delete([fileprefix, '.hdr']); 68 | elseif filetype == 2 69 | gzip([fileprefix, '.nii']); 70 | delete([fileprefix, '.nii']); 71 | end; 72 | end; 73 | 74 | % % So earlier versions of SPM can also open it with correct originator 75 | % % 76 | % if filetype == 0 77 | % M=[[diag(nii.hdr.dime.pixdim(2:4)) -[nii.hdr.hist.originator(1:3).*nii.hdr.dime.pixdim(2:4)]'];[0 0 0 1]]; 78 | % save(fileprefix, 'M'); 79 | % elseif filetype == 1 80 | % M=[]; 81 | % save(fileprefix, 'M'); 82 | %end 83 | 84 | return % save_untouch_nii 85 | 86 | 87 | %----------------------------------------------------------------------------------- 88 | function write_nii(nii, filetype, fileprefix) 89 | 90 | hdr = nii.hdr; 91 | 92 | if isfield(nii,'ext') & ~isempty(nii.ext) 93 | ext = nii.ext; 94 | [ext, esize_total] = verify_nii_ext(ext); 95 | else 96 | ext = []; 97 | end 98 | 99 | switch double(hdr.dime.datatype), 100 | case 1, 101 | hdr.dime.bitpix = int16(1 ); precision = 'ubit1'; 102 | case 2, 103 | hdr.dime.bitpix = int16(8 ); precision = 'uint8'; 104 | case 4, 105 | hdr.dime.bitpix = int16(16); precision = 'int16'; 106 | case 8, 107 | hdr.dime.bitpix = int16(32); precision = 'int32'; 108 | case 16, 109 | hdr.dime.bitpix = int16(32); precision = 'float32'; 110 | case 32, 111 | hdr.dime.bitpix = int16(64); precision = 'float32'; 112 | case 64, 113 | hdr.dime.bitpix = int16(64); precision = 'float64'; 114 | case 128, 115 | hdr.dime.bitpix = int16(24); precision = 'uint8'; 116 | case 256 117 | hdr.dime.bitpix = int16(8 ); precision = 'int8'; 118 | case 512 119 | hdr.dime.bitpix = int16(16); precision = 'uint16'; 120 | case 768 121 | hdr.dime.bitpix = int16(32); precision = 'uint32'; 122 | case 1024 123 | hdr.dime.bitpix = int16(64); precision = 'int64'; 124 | case 1280 125 | hdr.dime.bitpix = int16(64); precision = 'uint64'; 126 | case 1792, 127 | hdr.dime.bitpix = int16(128); precision = 'float64'; 128 | otherwise 129 | error('This datatype is not supported'); 130 | end 131 | 132 | % hdr.dime.glmax = round(double(max(nii.img(:)))); 133 | % hdr.dime.glmin = round(double(min(nii.img(:)))); 134 | 135 | if filetype == 2 136 | fid = fopen(sprintf('%s.nii',fileprefix),'w'); 137 | 138 | if fid < 0, 139 | msg = sprintf('Cannot open file %s.nii.',fileprefix); 140 | error(msg); 141 | end 142 | 143 | hdr.dime.vox_offset = 352; 144 | 145 | if ~isempty(ext) 146 | hdr.dime.vox_offset = hdr.dime.vox_offset + esize_total; 147 | end 148 | 149 | hdr.hist.magic = 'n+1'; 150 | save_untouch_nii_hdr(hdr, fid); 151 | 152 | if ~isempty(ext) 153 | save_nii_ext(ext, fid); 154 | end 155 | elseif filetype == 1 156 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 157 | 158 | if fid < 0, 159 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 160 | error(msg); 161 | end 162 | 163 | hdr.dime.vox_offset = 0; 164 | hdr.hist.magic = 'ni1'; 165 | save_untouch_nii_hdr(hdr, fid); 166 | 167 | if ~isempty(ext) 168 | save_nii_ext(ext, fid); 169 | end 170 | 171 | fclose(fid); 172 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 173 | else 174 | fid = fopen(sprintf('%s.hdr',fileprefix),'w'); 175 | 176 | if fid < 0, 177 | msg = sprintf('Cannot open file %s.hdr.',fileprefix); 178 | error(msg); 179 | end 180 | 181 | save_untouch0_nii_hdr(hdr, fid); 182 | 183 | fclose(fid); 184 | fid = fopen(sprintf('%s.img',fileprefix),'w'); 185 | end 186 | 187 | ScanDim = double(hdr.dime.dim(5)); % t 188 | SliceDim = double(hdr.dime.dim(4)); % z 189 | RowDim = double(hdr.dime.dim(3)); % y 190 | PixelDim = double(hdr.dime.dim(2)); % x 191 | SliceSz = double(hdr.dime.pixdim(4)); 192 | RowSz = double(hdr.dime.pixdim(3)); 193 | PixelSz = double(hdr.dime.pixdim(2)); 194 | 195 | x = 1:PixelDim; 196 | 197 | if filetype == 2 & isempty(ext) 198 | skip_bytes = double(hdr.dime.vox_offset) - 348; 199 | else 200 | skip_bytes = 0; 201 | end 202 | 203 | if double(hdr.dime.datatype) == 128 204 | 205 | % RGB planes are expected to be in the 4th dimension of nii.img 206 | % 207 | if(size(nii.img,4)~=3) 208 | error(['The NII structure does not appear to have 3 RGB color planes in the 4th dimension']); 209 | end 210 | 211 | nii.img = permute(nii.img, [4 1 2 3 5 6 7 8]); 212 | end 213 | 214 | % For complex float32 or complex float64, voxel values 215 | % include [real, imag] 216 | % 217 | if hdr.dime.datatype == 32 | hdr.dime.datatype == 1792 218 | real_img = real(nii.img(:))'; 219 | nii.img = imag(nii.img(:))'; 220 | nii.img = [real_img; nii.img]; 221 | end 222 | 223 | if skip_bytes 224 | fwrite(fid, zeros(1,skip_bytes), 'uint8'); 225 | end 226 | 227 | fwrite(fid, nii.img, precision); 228 | % fwrite(fid, nii.img, precision, skip_bytes); % error using skip 229 | fclose(fid); 230 | 231 | return; % write_nii 232 | 233 | -------------------------------------------------------------------------------- /NIfTI_20140122/unxform_nii.m: -------------------------------------------------------------------------------- 1 | % Undo the flipping and rotations performed by xform_nii; spit back only 2 | % the raw img data block. Initial cut will only deal with 3D volumes 3 | % strongly assume we have called xform_nii to write down the steps used 4 | % in xform_nii. 5 | % 6 | % Usage: a = load_nii('original_name'); 7 | % manipulate a.img to make array b; 8 | % 9 | % if you use unxform_nii to un-tranform the image (img) data 10 | % block, then nii.original.hdr is the corresponding header. 11 | % 12 | % nii.original.img = unxform_nii(a, b); 13 | % save_nii(nii.original,'newname'); 14 | % 15 | % Where, 'newname' is created with data in the same space as the 16 | % original_name data 17 | % 18 | % - Jeff Gunter, 26-JUN-06 19 | % 20 | function outblock = unxform_nii(nii, inblock) 21 | 22 | if isempty(nii.hdr.hist.rot_orient) 23 | outblock=inblock; 24 | else 25 | [dummy unrotate_orient] = sort(nii.hdr.hist.rot_orient); 26 | outblock = permute(inblock, unrotate_orient); 27 | end 28 | 29 | if ~isempty(nii.hdr.hist.flip_orient) 30 | flip_orient = nii.hdr.hist.flip_orient(unrotate_orient); 31 | 32 | for i = 1:3 33 | if flip_orient(i) 34 | outblock = flipdim(outblock, i); 35 | end 36 | end 37 | end; 38 | 39 | return; 40 | 41 | -------------------------------------------------------------------------------- /NIfTI_20140122/verify_nii_ext.m: -------------------------------------------------------------------------------- 1 | % Verify NIFTI header extension to make sure that each extension section 2 | % must be an integer multiple of 16 byte long that includes the first 8 3 | % bytes of esize and ecode. If the length of extension section is not the 4 | % above mentioned case, edata should be padded with all 0. 5 | % 6 | % Usage: [ext, esize_total] = verify_nii_ext(ext) 7 | % 8 | % ext - Structure of NIFTI header extension, which includes num_ext, 9 | % and all the extended header sections in the header extension. 10 | % Each extended header section will have its esize, ecode, and 11 | % edata, where edata can be plain text, xml, or any raw data 12 | % that was saved in the extended header section. 13 | % 14 | % esize_total - Sum of all esize variable in all header sections. 15 | % 16 | % NIFTI data format can be found on: http://nifti.nimh.nih.gov 17 | % 18 | % - Jimmy Shen (jimmy@rotman-baycrest.on.ca) 19 | % 20 | function [ext, esize_total] = verify_nii_ext(ext) 21 | 22 | if ~isfield(ext, 'section') 23 | error('Incorrect NIFTI header extension structure.'); 24 | elseif ~isfield(ext, 'num_ext') 25 | ext.num_ext = length(ext.section); 26 | elseif ~isfield(ext, 'extension') 27 | ext.extension = [1 0 0 0]; 28 | end 29 | 30 | esize_total = 0; 31 | 32 | for i=1:ext.num_ext 33 | if ~isfield(ext.section(i), 'ecode') | ~isfield(ext.section(i), 'edata') 34 | error('Incorrect NIFTI header extension structure.'); 35 | end 36 | 37 | ext.section(i).esize = ceil((length(ext.section(i).edata)+8)/16)*16; 38 | ext.section(i).edata = ... 39 | [ext.section(i).edata ... 40 | zeros(1,ext.section(i).esize-length(ext.section(i).edata)-8)]; 41 | esize_total = esize_total + ext.section(i).esize; 42 | end 43 | 44 | return % verify_nii_ext 45 | 46 | -------------------------------------------------------------------------------- /Pychange.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/Pychange.m -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The Project of Segmentation and 3D Reconstruction of NeuroVasculature Unit 2 | 3 | 1. We have four sub-projects list in follow. 4 | 5 | https://github.com/Pandolph/Brain_Science_Image_Platform 6 | https://github.com/Pandolph/Matlab_Segmentation 7 | https://github.com/Pandolph/Opencv-using-SVM 8 | https://github.com/Pandolph/unet 9 | 10 | 2. Brain_Science_Image_Platform is the Main project 11 | example.m is the entrance 12 | 13 | Matlab_Segmentation includes the GUI and most of the 2D segmentaion parts. 14 | 15 | Opencv_using_SVM includes the 2D SVM segmentation implementated using C++ 16 | 17 | unet includes the 2D unet segmenation implemented using python 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /SVM.m: -------------------------------------------------------------------------------- 1 | out = imread('/Users/pan/Desktop/SVM/SVM/test.tif'); 2 | m = medfilt2(rgb2gray(out),[5,5]); 3 | imwrite(m,'/Users/pan/Desktop/SVM/SVM/m.tif') 4 | 5 | % SVM 6 | % Mat ForeImg = srcImg(Rect(256, 256, 30, 30));//2D, Rect(x,y,width,height) 7 | 8 | myelin = imread('/Users/pan/Desktop/SVM/SVM/result.jpg'); 9 | 10 | close all 11 | se = strel('disk',5); 12 | temp = imerode(myelin,se); 13 | se = strel('disk',1); 14 | k = imdilate(temp,se); 15 | figure;imshow(k); 16 | 17 | figure;imshow(manualmyelin(:,:,1),[]) 18 | i =1; 19 | [mPrecison,mRecall,mFmeasure] = AreaCoincidence(manualmyelin(:,:,1:i),k(:,:,1:i)); 20 | -------------------------------------------------------------------------------- /TiffChange.m: -------------------------------------------------------------------------------- 1 | function TiffChange(stack,name) 2 | %warning: it will change the file to unit8, which means the largest num is 3 | %255, num larger than 255 will become 255 automatically 4 | %stack = data; 5 | % for i = 1:size(stack,3) 6 | % tempMin = min(min(data(:,:,i))); 7 | % tempMax = max(max(data(:,:,i))); 8 | % stack(:,:,i) = data(:,:,i)/max(max()); 9 | % end 10 | imwrite(stack(:,:,1), name) 11 | for k = 2:size(stack,3) 12 | imwrite(stack(:,:,k), name, 'writemode', 'append'); 13 | end 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /TiffInput.m: -------------------------------------------------------------------------------- 1 | function Crop = TiffInput(channel) 2 | % input tiff, choose one of the tif pictures 3 | %channel = 'all', 'part', '1', '2', '3' 4 | [~,PathName] = uigetfile('*.tif','Select the file'); 5 | if strcmp(channel, 'all') 6 | Files = dir(fullfile(PathName,'*.tif')); 7 | elseif strcmp(channel, 'part') 8 | Files1 = dir(fullfile(PathName,['*','.tif'])); 9 | prompt = {'Start','End'}; 10 | dlg_title = 'Input'; 11 | num_lines = 1; 12 | defaultans = {'1','100'}; 13 | answer = inputdlg(prompt,dlg_title,num_lines,defaultans); 14 | Files = Files1([str2num(answer{1,1}):str2num(answer{2,1})],1); 15 | else 16 | Files = dir(fullfile(PathName,['*',num2str(channel),'.tif'])); 17 | end 18 | place = [PathName,Files(1).name]; 19 | tif = imread(place); % z = 156 slices, x = 437 or tif(:,1,1), y = 1379 or tif(1,:,1) 20 | sliceSize = length(Files(:,1)); 21 | Data = ones(length(tif(:,1,1)),length(tif(1,:,1)),sliceSize); 22 | for k = 1:sliceSize 23 | place = [PathName,Files(k,1).name]; 24 | tif = imread(place); 25 | Data(:,:,k) = tif(:,:,find(mean(mean(tif,1),2))); 26 | end 27 | 28 | Crop = Data; 29 | %Crop = crop(Data); 30 | -------------------------------------------------------------------------------- /VExample.m: -------------------------------------------------------------------------------- 1 | % example.m is the main file 2 | % the function canny in BloodVessel.m can't work under matlab version 2013a 3 | % in the selection part, some hidden tiff files may cause error, so delete those hidden files 4 | 5 | %% Processing of blood vessel 6 | Crop = TiffInput('all'); 7 | num_hist = 10; % the slice for histmatch 8 | x = 9; 9 | outHist = HistMatch(Crop,num_hist);figure;imshow(outHist(:,:,x),[]) 10 | Col = ColumnMatch(outHist);figure;imshow(Col(:,:,x),[]) 11 | filter_size =5; % the size of filer in the preprosessing to denoise 12 | filter_num =1; % how many times the filter is applied 13 | bi_threshold = 0.1; %the threshhold of binarization, larger means fewer area left 14 | Bi = MeanBi(Col,bi_threshold,filter_num,filter_size);figure;imshow(Bi(:,:,x),[]) 15 | 16 | % vessel = logical(Bi); 17 | 18 | % simplify preprocessing for large dataset 19 | BiVessel = bwareaopen(Bi,40,8); 20 | se = strel('disk',7); 21 | I = imdilate(BiVessel,se); 22 | vessel = imerode(I,se);figure;imshow(vessel(:,:,x),[]) 23 | 24 | % difficult pictures 25 | thresh_canny = [0.1 0.4]; %lower than low threshold means not edge, higher than high threshold means edge 26 | strel_size = 7; % morphology element size 27 | vessel = BloodVessel(Bi,thresh_canny,strel_size);figure;imshow(vessel(:,:,x),[]) 28 | 29 | save('vessel.mat','vessel') 30 | [vPrecison,vRecall,vFmeasure] = AreaCoincidence(manualvessel48,vessel); 31 | bin = 60; % display parameter 32 | mydisplay(Crop,bin); 33 | mydisplay(outHist,bin); 34 | mydisplay(Col,bin); 35 | 36 | save_nii(make_nii(uint16(vessel)),'vessel.nii'); %change 3d mat data to nii 37 | save_nii(make_nii(uint16(Crop)),'vesselCrop.nii'); 38 | %% computing 39 | %tracing is plug-in --> neuron tracing --> Vaa3D neuron2 --> Vaa3D neuron2 app1 40 | data = CombineVessel(vessel1, vessel2, cell); 41 | 42 | % vessel volume 43 | volper = VolPer(vessel); % volume percentage 44 | 45 | load('C:\Users\Administrator\CloudStation\Vessel\vessel_1024x1024_0.78umx0.78umx2um\vessel.mat') 46 | % expand and change 47 | x = 0.78; 48 | z = 2; 49 | h = z/x; 50 | squeeze = floor(h)/h; 51 | real = expand(vessel,h); 52 | %TiffChange(real,'vessel.tif'); %change 3d mat data to tiff file 53 | 54 | sample = vessel; 55 | % vessel 56 | [length, dia] = lenAnddia('vessel.tif_x323_y10_z28_app2.swc',squeeze); 57 | realDiaAverage = x*sqrt(sum(length.*(dia.^2))/sum(length)); 58 | LenVol = x*sum(length)*10^(-6)/(size(sample,1)*size(sample,2)*size(sample,3)*x^2*z*10^(-9)); 59 | percentage = sum((pi/4)*length.*(dia).^2)/(size(real,1)*size(real,2)*size(real,3)/(squeeze^3));%recheck the volume percentage 60 | 61 | %micro vessel 62 | micro = find(dia(:,1)<6/x); 63 | MicroDiaAve = x*sqrt(sum(length(micro).*(dia(micro).^2))/sum(length(micro))); 64 | MicroDensity = x*sum(length(micro))*10^(-6)/(size(sample,1)*size(sample,2)*size(sample,3)*x^2*z*10^(-9)); 65 | MicroVolume = sum((pi/4)*length(micro).*(dia(micro)).^2)/(size(real,1)*size(real,2)*size(real,3)/(squeeze^3)); 66 | 67 | %vessel histogram 68 | matHist = ones(12,2); 69 | for i = 1:12 70 | if i ==12 71 | matHist(i,2) = x*sum(length(find(dia(:,1)> 22 )))*10^(-6)/(size(sample,1)*size(sample,2)*size(sample,3)*x^2*z*10^(-9)); 72 | else 73 | low = 2*i-2; 74 | high = 2*i; 75 | matHist(i,2) = x*sum(length(find(dia(:,1)< high &dia(:,1)> low )))*10^(-6)/(size(sample,1)*size(sample,2)*size(sample,3)*x^2*z*10^(-9)); 76 | end 77 | matHist(i,1) = 2*i-2; 78 | end 79 | xlswrite('matHist2.xlsx',matHist); 80 | 81 | % cell vessel 82 | h = 3; % the length of z axis, attention! z/x 83 | [distance2d, distance3d]= CellDensity('vessel1.tif_x51_y432_z57_app2.swc',cell,h); %calculate the cell density 84 | 85 | % manual 86 | Crop2 = fliplr(rot90(Crop)); % to change the direction of nii file 87 | save_nii(make_nii(uint16(Crop)),'vesselCrop.nii'); 88 | temp = load_nii('ManualCell.nii');ManualCell = temp.img; 89 | 90 | %need to fix 91 | dia = diameter('vessel1.tif_x51_y432_z57_app2.swc','vessel2.tif_x3_y0_z14_app2.swc',vessel,h); % average diameter of vessel 92 | diaHist = DiameterHistogram('vessel1.tif_x50_y436_z57_app1.swc','vessel2.tif_x417_y152_z2_app1.swc'); -------------------------------------------------------------------------------- /VesselLineRead.m: -------------------------------------------------------------------------------- 1 | function [num, data]=VesselLineRead(name) 2 | % name = 'stack1.tif_x934_y242_z151_app2.swc' 3 | temp = load_v3d_swc_file(name); 4 | num = length(temp); 5 | data = temp(:,3:5); 6 | 7 | -------------------------------------------------------------------------------- /VolPer.m: -------------------------------------------------------------------------------- 1 | function volper = VolPer(vessel) 2 | % compute the volume percentage 3 | volper = length(find(vessel))/(length(vessel(1,1,:))*length(vessel(1,:,1))*length(vessel(:,1,1))); 4 | volmat = ones(length(vessel(1,1,:)),1); 5 | for i = 1 : length(vessel(1,1,:)) 6 | volmat(i,1) = length(find(vessel(:,:,i)))/(length(vessel(1,:,1))*length(vessel(:,1,1))); 7 | end 8 | figure;plot(volmat); 9 | -------------------------------------------------------------------------------- /canny/Contents.m: -------------------------------------------------------------------------------- 1 | % CANNY 2 | % 3 | % Files 4 | % canny - is an implementation of the Canny edge detector 5 | % checkattributes - is like VALIDATEATTRIBUTES but returns true or false 6 | % exindex - extended array indexing 7 | % fractile - finds fractiles of a distribution 8 | % gradients_n - Estimate gradients in N dimensions with Gaussian smoothing 9 | % gsmoothn - Gaussian N-dimensional array smoothing 10 | % hystThresh - carries out hysteresis thresholding, as for Canny 11 | % nonmaxSuppress - does non-maximum suppression on 2-D and 3-D arrays 12 | -------------------------------------------------------------------------------- /canny/checkattributes.m: -------------------------------------------------------------------------------- 1 | function ok = checkattributes(a, classes, attributes) 2 | %CHECKATTRIBUTES is like VALIDATEATTRIBUTES but returns true or false 3 | % OK = CHECKATTRIBUTES(A,CLASSES,ATTRIBUTES) takes the same arguments as 4 | % VALIDATEATTRIBUTES, excluding the three optional arguments. However 5 | % CHECKATTRIBUTES returns true or false when VALIDATEATTRIBUTES would 6 | % return or throw an exception respectively. 7 | % 8 | % See also VALIDATEATTRIBUTES. 9 | 10 | try 11 | validateattributes(a, classes, attributes, 'checkattributes'); 12 | ok = true; 13 | catch ME 14 | if ~isempty(strfind(ME.identifier, ':checkattributes:')) 15 | ok = false; % first argument failed the specified tests 16 | else 17 | rethrow(ME); % there was some other error 18 | end 19 | end 20 | end -------------------------------------------------------------------------------- /canny/fractile.m: -------------------------------------------------------------------------------- 1 | function t = fractile(x, f) 2 | %FRACTILE finds fractiles of a distribution 3 | % T = FRACTILE(X, F) finds a value T for which a fraction F of the 4 | % elements of X are less than T. A fractile is like a centile, except 5 | % that the argument is a fraction rather then a percentage. 6 | % 7 | % Linear interpolation is used between data points. The minimum and 8 | % maximum values in X are returned for F=0 and F=1 respectively. F may be 9 | % a matrix; the result is the corresponding matrix of fractiles. 10 | 11 | % Note on the algorithm: 12 | % Forming a histogram seems to take as long as SORT, but sort is much 13 | % simpler, since histogramming always needs to be used recursively to work 14 | % with uneven distributions. However, for very large amounts of data it may 15 | % be worthwhile to look at providing a recursive histogram method. 16 | 17 | validateattributes(x, {'numeric'}, {}); 18 | validateattributes(f, {'numeric'}, {'>=' 0 '<=' 1}); 19 | 20 | x = sort(x(:)); 21 | n = numel(x); 22 | fn = n * f(:); % the ideal index into sorted g 23 | 24 | i = floor(fn + 0.5); % index of value just less than f 25 | 26 | ga = x(max(i, 1)); 27 | gb = x(min(i+1, n)); 28 | 29 | r = fn + 0.5 - i; 30 | t = (1-r) .* ga + r .* gb; % interpolate 31 | 32 | t = reshape(t, size(f)); 33 | 34 | end -------------------------------------------------------------------------------- /canny/gradients_n.m: -------------------------------------------------------------------------------- 1 | function [g, region] = gradients_n(a, varargin) 2 | %GRADIENTS_N Estimate gradients in N dimensions with Gaussian smoothing 3 | % [G, REGION] = GRADIENTS_N(A) estimates the gradients of A using centred 4 | % differences. 5 | % 6 | % A is an N-D array of class double or single. Its dimensionality D 7 | % is given by NDIMS(A) unless A is a column vector, when D = 1. 8 | % 9 | % G is a cell array of estimates of the gradients, computed using 10 | % symmetric differencing between the two nearest neighbours of each 11 | % voxel on the axis under consideration. G{1} is the gradient along 12 | % the first dimension of A, etc. Each array will be smaller than A to 13 | % avoid needing to extrapolate A. 14 | % 15 | % REGION is the region of A for which gradients have been computed, 16 | % given as a 2*D vector with the minimum and maximum indices for each 17 | % dimension. In the non-smoothing case it will be [2 size(A,1)-1 2 18 | % size(A,2)-1 ...]. 19 | % 20 | % [G, REGION] = GRADIENTS_N(A, SIGMAS) carries out Gaussian smoothing and 21 | % differencing to estimate the gradients of A along each dimension. 22 | % 23 | % SIGMAS specifies smoothing constants. It may be: 24 | % 25 | % A vector of length D of the form [SIGMA1, SIGMA2, ...]. SIGMA1, 26 | % SIGMA2 etc. are the "sigma" parameters of the 1D Gaussian masks 27 | % used for smoothing along each dimension of A. (Note that the 28 | % order of the first two constants is different to that used in 29 | % GRADIENTS_XY and GRADIENTS_XYT.) 30 | % 31 | % A scalar, in which case the same constant is used on all 32 | % dimensions. If SIGMAS is zero, no smoothing is done. 33 | % 34 | % The output arrays will be smaller than the input array in order to 35 | % avoid having to extrapolate beyond the boundaries of the array. The 36 | % result REGION reports the region of the input array for which the 37 | % output values have been estimated, in the form [MIN1, MAX1, MIN2, 38 | % MAX2, ...] where MIN1 and MAX1 are the limits of the region on the 39 | % first dimension, etc. The size of the output arrays is 40 | % [MAX1-MIN1+1, MAX2-MIN2+1, ...]. The reduction in size depends on 41 | % the smoothing parameters, and is chosen so that the smoothing masks 42 | % are a good approximation to the untruncated Gaussian mask. 43 | % 44 | % REGION = GRADIENTS_N(A, SIGMAS, 'RegionOnly') returns only the region. 45 | % 46 | % [G, REGION] = GRADIENTS_N(A, SIGMAS, NAME, VALUE, ...) 47 | % [G, REGION] = GRADIENTS_N(A, NAME, VALUE, ...) 48 | % set additional parameters using name-value pairs. Names may be: 49 | % 50 | % 'Region' - Specifies a region of interest in A. Its value may be: 51 | % 52 | % 'valid' or [] (default) - As described above. 53 | % 54 | % 'same' - The region of interest covers the whole of A, and the 55 | % output array has the same size as A. Reflection at the 56 | % boundaries is used to extrapolate A on dimensions where it does 57 | % not wrap around. 58 | % 59 | % A 2*D-element row vector with elements [MIN1, MAX1, MIN2, MAX2, 60 | % ...] describing a rectangular volume. The results arrays will 61 | % have size [MAX1-MIN1+1, MAX2-MIN2+1, ...] and will contain the 62 | % smoothed values for the specified region of the input array. 63 | % Reflection at the boundaries is used for extrapolation of A 64 | % when necessary. 65 | % 66 | % 'Wrap' - Specifies that the array wraps round (i.e. has periodic 67 | % boundary conditions) on one or more axes. The value may be: 68 | % 69 | % A logical vector of length D of the form [WRAP1, WRAP2, ...]. 70 | % If WRAP1 is true the first dimension is circular, etc. If a 71 | % dimension wraps, the size of that dimension will not be reduced 72 | % in the default output region. 73 | % 74 | % A logical scalar specifying that all dimensions are or are not 75 | % circular. The default is false. 76 | % 77 | % [] - Same as false. 78 | % 79 | % 'Centred' - Specifies whether centred differencing is used: 80 | % 81 | % true (default) - Gradient estimates are at voxel centres. Thus 82 | % G{Q}(I,J,...) is a gradient estimate centred on A(I,J,...) if 83 | % the 'same' region specification is used. Otherwise it is 84 | % centred on A(I-REGION(1)+1, J-REGION(3)+1, ...). This is 85 | % achieved by centred differencing, using the two nearest 86 | % neighbours along the Q dimension. 87 | % 88 | % false - Gradient estimates are at voxel corners. Thus 89 | % G{Q}(I,J,...) is a gradient estimate centred on A(I-0.5, J-0.5, 90 | % ...) if the 'same' region specification is used. Otherwise it 91 | % is centred on A(I-REGION(1)+0.5, J-REGION(3)+0.5, ...). This is 92 | % achieved by differencing the average values on opposite faces 93 | % of a voxel-sized hypercube. The estimate is more localised than 94 | % for centred differencing, but is offset towards the origin 95 | % relative to the corresponding element of A. 96 | % 97 | % See also: gradients_x, gradients_xy, gradients_xyt, gsmoothn 98 | 99 | % Copyright David Young 2014 100 | 101 | % check arguments and get defaults 102 | [sigmas, wraps, region, regonly, d, symdiff, dmargin] = ... 103 | checkinputs(a, varargin{:}); 104 | 105 | % can stop now if only the region to be returned 106 | if regonly 107 | g = region; 108 | return; 109 | end 110 | 111 | % expand the region to allow for subsequent differencing operation 112 | regdiff = region + repmat(dmargin, 1, d); 113 | 114 | % region selection and spatial smoothing (do this before sum and difference 115 | % to reduce processing if region is small) 116 | asmth = gsmoothn(a, sigmas, 'Region', regdiff, 'Wrap', wraps); 117 | 118 | % Differencing mask 119 | if symdiff 120 | % get the average gradient over 2 voxels so centred 121 | dmask = [1; 0; -1]/2; 122 | % Index ranges for trimming undifferenced dimensions 123 | sz = size(asmth); 124 | sz = sz(1:d); % omit trailing 1 in 1-D case 125 | triminds = arrayfun(@(x) 2:x-1, sz, 'UniformOutput', false); 126 | else 127 | % take adjacent voxels, not centred on voxel 128 | dmask = repmat([1; -1]/(2^(d-1)), [1 2+zeros(1,d-1)]); 129 | end 130 | 131 | g = cell(1, d); 132 | perm = (1:max(2,d)).'; % permute needs at least 2 dimensions to order 133 | 134 | for i = 1:d 135 | 136 | % orient mask along current dimension 137 | dmaskr = permute(dmask, circshift(perm, i-1)); 138 | 139 | if symdiff 140 | % trim other dimensions so outputs all same size 141 | t = triminds; 142 | t{i} = 1:sz(i); % 143 | g{i} = convn(asmth(t{:}), dmaskr, 'valid'); 144 | else 145 | g{i} = convn(asmth, dmaskr, 'valid'); 146 | end 147 | 148 | 149 | end 150 | 151 | end 152 | 153 | % ------------------------------------------------------------------------- 154 | 155 | function [sigmas, wraps, region, regonly, d, symdiff, dmargin] = ... 156 | checkinputs(a, varargin) 157 | % Check arguments and get defaults 158 | 159 | % Most checking done in gsmoothn, no need here 160 | inp = inputParser; 161 | inp.addOptional('sigma', 0); 162 | inp.addOptional('regonly', '', @(s) strcmp(s, 'RegionOnly')); 163 | inp.addParameter('Region', []); 164 | inp.addParameter('Wrap', []); 165 | inp.addParameter('Centred', true); 166 | inp.parse(varargin{:}); 167 | regonly = ~isempty(inp.Results.regonly); 168 | sigmas = inp.Results.sigma; 169 | region = inp.Results.Region; 170 | wraps = inp.Results.Wrap; 171 | symdiff = inp.Results.Centred; 172 | 173 | % number of dimensions, defined as number of last non-singleton dimension 174 | if iscolumn(a) 175 | d = 1; 176 | else 177 | d = ndims(a); 178 | end 179 | 180 | if isempty(wraps) 181 | wraps = false(1, d); 182 | elseif isscalar(wraps) 183 | wraps = repmat(wraps, 1, d); 184 | end 185 | 186 | if symdiff 187 | dmargin = [-1 1]; % region margin for differencing 188 | else 189 | dmargin = [-1 0]; 190 | end 191 | 192 | if isempty(region) || strcmp(region, 'valid') 193 | % default region - small enough not to need extrapolation 194 | region = gsmoothn(a, sigmas, 'RegionOnly', 'Wrap', wraps); 195 | % -dmargin because contracting to get output region 196 | region = region + ... 197 | repmat(-dmargin, 1, d) .* double(~reshape([wraps; wraps], 1, 2*d)); 198 | elseif strcmp(region, 'same') 199 | sz = size(a); 200 | region = reshape([ones(1, d); sz(1:d)], 1, 2*d); 201 | end 202 | if any(region(2:2:end) < region(1:2:end)) 203 | error('DavidYoung:gradients_n:badreg', ... 204 | 'REGION or array size too small'); 205 | end 206 | 207 | end 208 | 209 | -------------------------------------------------------------------------------- /canny/gsmoothn.m: -------------------------------------------------------------------------------- 1 | function [a, reg] = gsmoothn(a, sigmas, varargin) 2 | %GSMOOTHN Gaussian N-dimensional array smoothing 3 | % [SMOOTH, REGION] = GSMOOTHN(A, SIGMAS) carries out Gaussian 4 | % smoothing on an N-dimensional array. 5 | % 6 | % A must be an array of class double or single. Its dimensionality D is 7 | % given by NDIMS(A) unless A is a column vector, when D = 1. 8 | % 9 | % SIGMAS specifies smoothing constants. This may be: 10 | % 11 | % A vector of length D of the form [SIGMA1, SIGMA2, ...]. SIGMA1, 12 | % SIGMA2 etc. are the "sigma" parameters of the 1D Gaussian masks 13 | % used for smoothing along each dimension of A. (Note that the order 14 | % of the first two constants is different to that used in 15 | % GRADIENTS_XY and GRADIENTS_XYT.) 16 | % 17 | % A scalar, in which case the same constant is used on all 18 | % dimensions. 19 | % 20 | % SMOOTH is the output array of smoothed values. 21 | % 22 | % The output array will be smaller than the input array in order to 23 | % avoid having to extrapolate beyond the boundaries of the array. The 24 | % result REGION reports the region of the input array for which 25 | % corresponding output values have been computed, in the form [MIN1, 26 | % MAX1, MIN2, MAX2, ...] where MIN1 and MAX1 are the limits of the 27 | % region on the first dimension, etc. The size of the output array is 28 | % [MAX1-MIN1+1, MAX2-MIN2+1, ...]. The reduction in size depends on 29 | % the smoothing parameters, and is chosen so that the smoothing masks 30 | % are a good approximation to the untruncated Gaussian mask. 31 | % 32 | % REGION = GSMOOTHN(A, SIGMAS, 'RegionOnly') returns only the region. 33 | % 34 | % [SMOOTH, REGION] = GSMOOTHN(A, SIGMAS, NAME, VALUE, ...) sets 35 | % additional parameters using name-value pairs. Names may be: 36 | % 37 | % 'Region' - Specifies a region of interest in A. Its value may be: 38 | % 39 | % 'valid' or [] (default) - As described above. 40 | % 41 | % 'same' - The region of interest covers the whole of A, and the 42 | % output array has the same size as A. Reflection at the 43 | % boundaries is used to extrapolate A on dimensions where it does 44 | % not wrap around. 45 | % 46 | % A 2*D-element row vector with elements [MIN1, MAX1, MIN2, MAX2, 47 | % ...] describing a rectangular volume. The results array will 48 | % have size [MAX1-MIN1+1, MAX2-MIN2+1, ...] and will contain the 49 | % smoothed values for the specified region of the input array. 50 | % Reflection at the boundaries is used for extrapolation of A 51 | % when necessary. 52 | % 53 | % 'Wrap' - Specifies that the array wraps round (i.e. has periodic 54 | % boundary conditions) on one or more axes. The value may be: 55 | % 56 | % A logical vector of length D of the form [WRAP1, WRAP2, ...]. 57 | % If WRAP1 is true the first dimension is circular, etc. If a 58 | % dimension wraps, the size of that dimension will not be reduced 59 | % in the default output region. 60 | % 61 | % A logical scalar specifying that all dimensions are or are not 62 | % circular. The default is false. 63 | % 64 | % [] - Same as false. 65 | % 66 | % See also: GSMOOTH, GSMOOTH2 67 | 68 | % Copyright David Young 2014 69 | 70 | [sigmas, bcons, reg, convreg, ronly, d] = ... 71 | checkinputs(a, sigmas, varargin{:}); 72 | 73 | if ronly 74 | a = reg; 75 | else 76 | if ~isempty(convreg) % trim/pad array 77 | lims = mat2cell(convreg, 1, repmat(2, 1, d)); 78 | lims = cellfun(@(x) x(1):x(2), lims, 'UniformOutput', false); 79 | indargs = cell(1, 2*d); 80 | indargs(1:2:end) = lims; 81 | indargs(2:2:end) = bcons; 82 | 83 | a = exindex(a, indargs{:}); 84 | end 85 | for i = 1:d 86 | a = gsmooth1(a, i, sigmas(i)); 87 | end 88 | end 89 | 90 | end 91 | 92 | % ------------------------------------------------------------------------- 93 | 94 | function [sigmas, bcons, reg, convreg, regonly, d] = ... 95 | checkinputs(a, sigmas, varargin) 96 | % Check arguments and get defaults, plus input/output convolution regions 97 | % and boundary conditions 98 | 99 | % array argument 100 | validateattributes(a, {'double' 'single'}, {}, mfilename, 'a'); 101 | 102 | % number of dimensions, defined as number of last non-singleton dimension 103 | if iscolumn(a) 104 | d = 1; 105 | else 106 | d = ndims(a); 107 | end 108 | 109 | % sigmas argument 110 | validateattributes(sigmas, {'double'}, {'nonnegative' 'real' 'vector'}, ... 111 | mfilename, 'sigmas'); 112 | if isscalar(sigmas) 113 | sigmas = repmat(sigmas, 1, d); 114 | elseif ~isequal(length(sigmas), d) 115 | error('DavidYoung:gsmoothn:badsigmas', 'SIGMAS wrong size'); 116 | end 117 | 118 | inp = inputParser; 119 | inp.addOptional('regonly', '', @(s) strcmp(s, 'RegionOnly')); 120 | % no need for region elements to be positive 121 | inp.addParameter('Region', [], @(r) ... 122 | isempty(r) || ... 123 | (ischar(r) && ismember(r, {'valid' 'same'})) || ... 124 | checkattributes(r, {'numeric'}, {'integer' 'size' [1 2*d]})); 125 | inp.addParameter('Wrap', [], @(w) ... 126 | isempty(w) || ... 127 | (islogical(w) && (isscalar(w) || isequal(size(w), [1 d])))); 128 | inp.parse(varargin{:}); 129 | 130 | % wraps argument 131 | wraps = inp.Results.Wrap; 132 | if isempty(wraps) 133 | wraps = false(1, d); 134 | elseif isscalar(wraps) 135 | wraps = repmat(wraps, 1, d); 136 | end 137 | boundopts = {'symmetric' 'circular'}; 138 | bcons = boundopts(wraps+1); 139 | 140 | % region argument 141 | regonly = ~isempty(inp.Results.regonly); 142 | reg = inp.Results.Region; 143 | 144 | % whole array region 145 | sz = size(a); 146 | imreg = reshape([ones(1, d); sz(1:d)], 1, 2*d); 147 | 148 | % convolution margins and wrap multipliers 149 | mrg = gausshsize(sigmas); 150 | mrg = reshape([mrg; -1*mrg], 1, 2*d); 151 | 152 | if isempty(reg) || strcmp(reg, 'valid') 153 | % default region - small enough not to need extrapolation - shrink on 154 | % non-wrapped dimensions 155 | reg = imreg + mrg .* double(~reshape([wraps; wraps], 1, 2*d)); 156 | elseif strcmp(reg, 'same') 157 | reg = imreg; 158 | end 159 | if any(reg(2:2:end) < reg(1:2:end)) 160 | error('DavidYoung:gsmoothn:badreg', 'REGION or array size too small'); 161 | end 162 | % compute input region for convolution - expand on all dimensions 163 | convreg = reg - mrg; % expand 164 | if isequal(convreg, imreg) 165 | convreg = []; % signal no trimming or padding 166 | end 167 | 168 | end 169 | 170 | % ------------------------------------------------------------------------- 171 | 172 | function a = gsmooth1(a, dim, sigma) 173 | % Smooth an array A along dimension DIM with a 1D Gaussian mask of 174 | % parameter SIGMA 175 | 176 | if sigma > 0 177 | mlen = 2*gausshsize(sigma) + 1; % reasonable truncation 178 | mask = fspecial('gauss', [mlen 1], sigma); 179 | msize = ones(1, ndims(a)); 180 | msize(dim) = mlen; 181 | mask = reshape(mask, msize); 182 | 183 | a = convn(a, mask, 'valid'); 184 | end 185 | 186 | end 187 | 188 | % ------------------------------------------------------------------------- 189 | 190 | function hsize = gausshsize(sigma) 191 | % Default for the limit on a Gaussian mask of parameter sigma. 192 | % Produces a reasonable degree of truncation without too much error. 193 | hsize = ceil(2.6*sigma); 194 | end 195 | 196 | -------------------------------------------------------------------------------- /canny/hystThresh.m: -------------------------------------------------------------------------------- 1 | function e = hystThresh(e, g, thresh, conn) 2 | %HYSTTHRESH carries out hysteresis thresholding, as for Canny 3 | % E = HYSTTHRESH(E, G, THRESH) takes a raw edge map, a gradient magnitude 4 | % array and a threshold or pair of thresholds, and returns a new edge map 5 | % wherever the gradient magnitude exceeds or equals the lower threshold 6 | % and is connected to a position where the gradient exceeds or equals the 7 | % higher threshold. 8 | % 9 | % E - a logical N-D array, giving the raw edge map 10 | % 11 | % G - the underlying array of gradients (or other values); should not 12 | % contain negative values; same size as E 13 | % 14 | % THRESH - a vector of the form [LOW HIGH] giving the lower and 15 | % higher thresholding values. If thresh is a scalar, simple 16 | % thresholding is carried out. Should contain positive values, with 17 | % HIGH > LOW. 18 | % 19 | % E = HYSTTHRESH(E, G, THRESH, CONN) allows the connectivity to be set. 20 | % 21 | % CONN - an integer giving the neighbourhood size to establish 22 | % connected regions. The default (if empty or omitted) is as for 23 | % IMRECONSTRUCT. 24 | % 25 | % See also: canny, imreconstruct 26 | 27 | ge = g .* e; 28 | 29 | e = ge > thresh(1); % simple thresholding, or lower bound 30 | 31 | if ~isscalar(thresh) 32 | e2 = ge > thresh(2); 33 | if nargin < 4 || isempty(conn) 34 | e = imreconstruct(e2, e); 35 | else 36 | e = imreconstruct(e2, e, conn); 37 | end 38 | end 39 | 40 | end -------------------------------------------------------------------------------- /canny/license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, David Young 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in 12 | the documentation and/or other materials provided with the distribution 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 18 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 | POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /canny/nonmaxSuppress.m: -------------------------------------------------------------------------------- 1 | function [e, gMag] = nonmaxSuppress(varargin) 2 | %NONMAXSUPPRESS does non-maximum suppression on 2-D and 3-D arrays 3 | % E = NONMAXSUPPRESS(G, NAME, VALUE, ...) finds directional local maxima 4 | % in a gradient array, as used in the Canny edge detector, but made 5 | % separately accessible here for greater flexibility. The result is a 6 | % logical array with the value true where the gradient magnitude is a 7 | % local maximum along the gradient direction. 8 | % 9 | % G is a cell array containing the components of the gradient, of length 10 | % 2 or 3. All the elements of G must have the same size; they must be 2-D 11 | % if the length of G is 2 or 3-D if the length of G is 3. 12 | % 13 | % [E, GMAG] = NONMAXSUPPRESS(G, NAME, VALUE, ...) also returns an array 14 | % containing the magnitude of the gradient at each point. 15 | % 16 | % Name-value pairs allow control over the process. Parameter names are: 17 | % 18 | % 'Method' - Specifies the algorithm used for interpolation amongst 19 | % neighbouring elements of the gradient magnitude array. For a point to 20 | % be marked as an edge, the gradient magnitude must be greater than the 21 | % interpolated magnitudes at two nearby points, one along the gradient 22 | % direction and the other in the opposite direction. Methods can be: 23 | % 24 | % 'boundary' (default) - Linear interpolation is carried out on the 25 | % boundary of the 2x2 square (in 2-D) or the 2x2x2 cube (in 3-D) 26 | % centred on the point being tested. 27 | % 28 | % 'nearest', 'linear', 'cubic', 'spline' - Interpolation is carried 29 | % out in 2-D or in 3-D. The method is passed to GRIDDEDINTERPOLANT. 30 | % 31 | % 'Radius' (default 1) - The distance along the gradient direction at 32 | % which the interpolation for each point is done. A value close to 1 is 33 | % recommended. This parameter is ignored if the 'boundary' method is 34 | % specified. 35 | % 36 | % 'SubPixel' (default false) - If true, sub-pixel interpolation is 37 | % carried out on the edge positions by fitting a parabola to the three 38 | % gradient magnitues round the peak. The result E will be a structure 39 | % with two fields: 40 | % 41 | % E.edge - a logical array with true at the edge positions 42 | % 43 | % E.subpix - In the 2-D case, if E.edge(I,J) is true, 44 | % E.subpix{1}(I,J) is the first (row) coordinate of the estimated 45 | % sub-pixel position of the edge point. E.subpix{2} gives the second 46 | % (column) coordinate. The 3-D case is similar. 47 | % 48 | % See also: canny, griddedInterpolant 49 | 50 | % Argument sorting out 51 | inp = inputParser; 52 | inp.addRequired('g', ... 53 | @(g) validateattributes(g, {'cell'}, {'vector'})); 54 | inp.addParameter('Method', 'boundary', ... 55 | @(s) ismember(s, {'boundary' 'linear' 'nearest' 'cubic' 'spline'})); 56 | inp.addParameter('Radius', 1, ... 57 | @(s) validateattributes(s, {'numeric'}, ... 58 | {'real' 'positive', 'nonnan', 'finite', 'scalar'})); 59 | inp.addParameter('SubPixel', false, ... 60 | @(s) validateattributes(s, {'logical'}, {'scalar'})); 61 | inp.parse(varargin{:}); 62 | g = inp.Results.g; 63 | method = inp.Results.Method; 64 | rad = inp.Results.Radius; 65 | 66 | % Get and check no. dimensions. Currently only to 2 or 3-D, but could 67 | % generalise to N if needed. 68 | ndim = length(g); 69 | if ndim < 2 || ndim > 3 70 | error('DavidYoung:nonmaxSuppression:dimsNot2or3', ... 71 | 'Length of gradients array must be 2 or 3, was %d', ndim); 72 | end 73 | 74 | % make the gradients into an array 75 | gcomps = cell2cols(g); 76 | 77 | % compute gradient magnitude array 78 | gMagCol = sqrt(sum(gcomps.^2, 2)); 79 | gMag = reshape(gMagCol, size(g{1})); 80 | 81 | % convert gradients to offsets 82 | if strcmp(method, 'boundary') 83 | % Make largest offset 1 - on boundary of square or cube. 84 | % Might expect that specialised code would be faster than general 85 | % interpolation in this case. Not so. 86 | [~, maxgradcomp] = max(abs(gcomps), [], 2); 87 | gnorm = gcomps(... 88 | sub2ind(size(gcomps), (1:size(gcomps,1)).', maxgradcomp)); 89 | method = 'linear'; % linear interp on square or cube boundary 90 | else 91 | % put on sphere of given radius 92 | gnorm = gMagCol / rad; 93 | end 94 | gcomps = bsxfun(@rdivide, gcomps, gnorm); 95 | 96 | % coords of data points in same format 97 | coords = arrayfun(@(s) 1:s, size(gMag), 'UniformOutput', false); 98 | [coords{:}] = ndgrid(coords{:}); 99 | coords = cell2cols(coords); 100 | 101 | % get interpolant 102 | interpolant = griddedInterpolant(gMag, method); 103 | 104 | % interpolate in gradient direction and its opposite 105 | ginta = interpolant(coords + gcomps); 106 | gintb = interpolant(coords - gcomps); 107 | 108 | % suppress nonmax pixels 109 | ok = gMag(:) >= ginta & gMag(:) >= gintb; 110 | 111 | edges = reshape(ok, size(gMag)); 112 | 113 | if inp.Results.SubPixel 114 | e.edge = edges; 115 | e.subpix = subpix(gMag, ginta, gintb, ok, coords, gcomps); 116 | else 117 | e = edges; 118 | end 119 | 120 | end 121 | 122 | 123 | function a = cell2cols(c) 124 | % put the arrays in cell array c into the columns of a 125 | a = cell2mat(cellfun(@(x) x(:), c, 'UniformOutput', false)); 126 | end 127 | 128 | 129 | function pos = subpix(gMag, ginta, gintb, ok, coords, gcomps) 130 | % points on parabola 131 | q = gMag(ok); 132 | r = ginta(ok) - q; % point in direction of gradient 133 | p = gintb(ok) - q; % opposite direction to gradient 134 | offset = (p-r)./(2*(p+r)); % scalar offset of peak 135 | offset = bsxfun(@times, offset, gcomps(ok, :)); % vector offset of peak 136 | offcoords = coords(ok, :) + offset; 137 | res = zeros(size(gMag)); 138 | for i = 1:size(coords,2) 139 | res(ok) = offcoords(:, i); 140 | pos{i} = res; 141 | end 142 | end 143 | -------------------------------------------------------------------------------- /cellErr.m: -------------------------------------------------------------------------------- 1 | function [cPrecison,cRecall,cFmeasure] = cellErr(manualcell,cell,distance) 2 | mCentroid = CentroidDetec(manualcell); 3 | cCentroid = CentroidDetec(cell); 4 | temp = cCentroid; 5 | 6 | for i = 1:length(mCentroid(:,1)) 7 | [D,I] = pdist2(temp,mCentroid(i,:),'euclidean','Smallest',1); 8 | if D < distance 9 | temp(I,:) = []; 10 | end 11 | end 12 | coincide = length(cCentroid(:,1))-length(temp(:,1)); 13 | cPrecison = coincide/length(cCentroid(:,1)); 14 | cRecall = coincide/length(mCentroid(:,1)); 15 | cFmeasure = 2*cPrecison*cRecall/(cRecall+cPrecison); 16 | 17 | % h = figure; 18 | % scatter3(mCentroid(1:end,1),mCentroid(1:end,2),mCentroid(1:end,3),'MarkerFaceColor','blue'); 19 | % hold on 20 | % scatter3(cCentroid(1:end,1),cCentroid(1:end,2),cCentroid(1:end,3),'MarkerFaceColor','red'); 21 | % axis equal -------------------------------------------------------------------------------- /crop.m: -------------------------------------------------------------------------------- 1 | function Crop = crop(Data) 2 | %crop 3 | Crop = Data; 4 | temp = []; 5 | for i = 1:length(Crop(:,1,1)) 6 | if ~sum(any(Crop(i,:,:))) 7 | temp = [temp i]; 8 | end 9 | end 10 | Crop(temp,:,:) =[]; 11 | temp = []; 12 | for i = 1:length(Crop(1,:,1)) 13 | if ~sum(any(Crop(:,i,:))) 14 | temp = [temp i]; 15 | end 16 | end 17 | Crop(:,temp,:) =[]; 18 | -------------------------------------------------------------------------------- /diameter.m: -------------------------------------------------------------------------------- 1 | function dia = diameter(vessel1,vessel2,vessel,h) 2 | % compute the length and the volume of vessel, then get the diameter 3 | temp = load_v3d_swc_file(vessel1); 4 | k1 = ones(length(temp(:,1))-1,1); 5 | for i = 1 : length(temp(:,1))-1 6 | k1(i,1) = sqrt((temp(i+1,3)-temp(temp(i+1,7),3))^2 + (temp(i+1,4)-temp(temp(i+1,7),4))^2 + ((temp(i+1,5)-temp(temp(i+1,7),5))*h)^2); 7 | end 8 | 9 | temp = load_v3d_swc_file(vessel2); 10 | k2 = ones(length(temp(:,1))-1,1); 11 | for i = 1 : length(temp(:,1))-1 12 | k2(i,1) = sqrt((temp(i+1,3)-temp(temp(i+1,7),3))^2 + (temp(i+1,4)-temp(temp(i+1,7),4))^2 + ((temp(i+1,5)-temp(temp(i+1,7),5))*h)^2); 13 | end 14 | 15 | dia = sqrt(4*length(find(vessel))*h /((sum(k1)+sum(k2))*pi)); -------------------------------------------------------------------------------- /expand.m: -------------------------------------------------------------------------------- 1 | function temp= expand(sample,h) 2 | % expand the sample to real scale and squeeze means paramter 3 | temp = false(size(sample,1),size(sample,2),floor(h)*size(sample,3)); 4 | for i = 1:size(sample,3) 5 | temp(:,:,floor(h)*(i-1)+1:floor(h)*i) = repmat(sample(:,:,i),1,1,floor(h)); 6 | end 7 | gap = h/(h-floor(h)); 8 | arrayx = round([1:floor(size(temp,1)/gap)]*gap); 9 | arrayy = round([1:floor(size(temp,2)/gap)]*gap); 10 | temp(arrayx,:,:) = []; 11 | temp(:,arrayy,:) = []; 12 | -------------------------------------------------------------------------------- /lenAnddia.m: -------------------------------------------------------------------------------- 1 | function [length, dia] = lenAnddia(vessel,squeeze) 2 | % vessel length 3 | temp2 = load_v3d_swc_file(vessel); 4 | temp3 = cat(2,temp2,ones(size(temp2,1),1)); 5 | 6 | for i = 1:size(temp3,1) 7 | if i == 1 8 | temp3(i,8) = 0; 9 | else 10 | node = temp3(i,7); 11 | temp3(i,8) = sqrt((temp3(i,3)-temp3(node,3))^2+(temp3(i,4)-temp3(node,4))^2+(temp3(i,5)-temp3(node,5))^2); 12 | end 13 | end 14 | length = temp3(:,8)/squeeze; 15 | dia = 2*temp3(:,6)/squeeze; -------------------------------------------------------------------------------- /manual.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/manual.mat -------------------------------------------------------------------------------- /matlab/getThemeThemes.csv: -------------------------------------------------------------------------------- 1 | -403:Need Privilege -------------------------------------------------------------------------------- /matlab/http_createHeader.m: -------------------------------------------------------------------------------- 1 | function header = http_createHeader(name,value) 2 | %http_createHeader Simple function for creating input header to urlread2 3 | % 4 | % header = http_createHeader(name,value) 5 | % 6 | % CODE: header = struct('name',name,'value',value); 7 | % 8 | % See Also: 9 | % urlread2 10 | 11 | header = struct('name',name,'value',value); -------------------------------------------------------------------------------- /matlab/http_paramsToString.m: -------------------------------------------------------------------------------- 1 | function [str,header] = http_paramsToString(params,encodeOption) 2 | %http_paramsToString Creates string for a POST or GET requests 3 | % 4 | % [queryString,header] = http_paramsToString(params, *encodeOption) 5 | % 6 | % INPUTS 7 | % ======================================================================= 8 | % params: cell array of property/value pairs 9 | % NOTE: If the input is in a 2 column matrix, then first column 10 | % entries are properties and the second column entries are 11 | % values, however this is NOT necessary (generally linear) 12 | % encodeOption: (default 1) 13 | % 1 - the typical URL encoding scheme (Java call) 14 | % 15 | % OUTPUTS 16 | % ======================================================================= 17 | % queryString: querystring to add onto URL (LACKS "?", see example) 18 | % header : the header that should be attached for post requests when 19 | % using urlread2 20 | % 21 | % EXAMPLE: 22 | % ============================================================== 23 | % params = {'cmd' 'search' 'db' 'pubmed' 'term' 'wtf batman'}; 24 | % queryString = http_paramsToString(params); 25 | % queryString => cmd=search&db=pubmed&term=wtf+batman 26 | % 27 | % IMPORTANT: This function does not filter parameters, sort them, 28 | % or remove empty inputs (if necessary), this must be done before hand 29 | 30 | if ~exist('encodeOption','var') 31 | encodeOption = 1; 32 | end 33 | 34 | if size(params,2) == 2 && size(params,1) > 1 35 | params = params'; 36 | params = params(:); 37 | end 38 | 39 | str = ''; 40 | for i=1:2:length(params) 41 | if (i == 1), separator = ''; else separator = '&'; end 42 | switch encodeOption 43 | case 1 44 | param = urlencode(params{i}); 45 | value = urlencode(params{i+1}); 46 | % case 2 47 | % param = oauth.percentEncodeString(params{i}); 48 | % value = oauth.percentEncodeString(params{i+1}); 49 | % header = http_getContentTypeHeader(1); 50 | otherwise 51 | error('Case not used') 52 | end 53 | str = [str separator param '=' value]; %#ok 54 | end 55 | 56 | switch encodeOption 57 | case 1 58 | header = http_createHeader('Content-Type','application/x-www-form-urlencoded'); 59 | end 60 | 61 | 62 | end -------------------------------------------------------------------------------- /matlab/samplecode.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/matlab/samplecode.m -------------------------------------------------------------------------------- /mydisplay.m: -------------------------------------------------------------------------------- 1 | function mydisplay(Data, bin) 2 | 3 | mat = ones(length(Data(1,1,:)),bin); 4 | for i = 1:length(Data(1,1,:)) 5 | slice = Data(:,:,i); 6 | slice = slice/max(slice(:)); 7 | [counts,x] = imhist(slice,bin); 8 | mat(i,:) = counts; 9 | end 10 | %figure;imshow(log(mat));title('log,imshow'); 11 | figure;imagesc(log(mat));title('log,imagesc'); 12 | -------------------------------------------------------------------------------- /unet.m: -------------------------------------------------------------------------------- 1 | place = '/Users/pan/Desktop'; 2 | manual = manualvessel48; 3 | Crop = TiffInput(1); 4 | dense = 46; 5 | matsize = 256; 6 | teststack = Crop(1:256,1:256,dense+1:dense+30); 7 | 8 | mkdir([place,'/data/test']); 9 | mkdir([place,'/data/train/image']); 10 | mkdir([place,'/data/train/label']); 11 | 12 | % reshape 13 | sizex = fix(size(manual,1)/matsize); 14 | sizey = fix(size(manual,2)/matsize); 15 | trainmat = []; 16 | manualmat = []; 17 | for i = 1:sizex 18 | for j = 1:sizey 19 | trainmat = cat(3,trainmat,Crop((i-1)*matsize+1:i*matsize,(j-1)*matsize+1:j*matsize,1:dense)); 20 | manualmat = cat(3,manualmat,manual((i-1)*matsize+1:i*matsize,(j-1)*matsize+1:j*matsize,1:dense)); 21 | end 22 | end 23 | num = size(manualmat,3); 24 | 25 | % from 256 to 512 26 | trainmatEnlarge = ones(512,512,size(trainmat,3)); 27 | teststackEnlarge = ones(512,512,size(teststack,3)); 28 | manualmatEnlarge = ones(512,512,size(manualmat,3)); 29 | 30 | for j = 1: size(trainmat,3) 31 | A=trainmat(:,:,j); 32 | b=ones(2); 33 | [m,n]=size(A); 34 | B=num2cell(A); 35 | C=cell(m*n,1); 36 | for i=1:m*n 37 | C{i}=B{i}*b; 38 | end 39 | trainmatEnlarge(:,:,j) = cell2mat(reshape(C,m,n)); 40 | end 41 | 42 | for j = 1: size(manualmat,3) 43 | A=manualmat(:,:,j); 44 | b=ones(2); 45 | [m,n]=size(A); 46 | B=num2cell(double(A)); 47 | C=cell(m*n,1); 48 | for i=1:m*n 49 | C{i}=B{i}*b; 50 | end 51 | manualmatEnlarge(:,:,j) = cell2mat(reshape(C,m,n)); 52 | end 53 | 54 | for j = 1: size(teststack,3) 55 | A=teststack(:,:,j); 56 | b=ones(2); 57 | [m,n]=size(A); 58 | B=num2cell(A); 59 | C=cell(m*n,1); 60 | for i=1:m*n 61 | C{i}=B{i}*b; 62 | end 63 | teststackEnlarge(:,:,j) = cell2mat(reshape(C,m,n)); 64 | end 65 | trainmat = trainmatEnlarge ; 66 | teststack = teststackEnlarge; 67 | manualmat = manualmatEnlarge; 68 | 69 | % input the train image files 70 | stack = trainmat; 71 | name = [place,'/data/train/image/']; 72 | for j = 1:num 73 | maxs = reshape(max(max(stack,[],2),[],1),[1,num]); 74 | temp = uint8(256*stack(:,:,j)/maxs(j)); 75 | imwrite(temp, [name,num2str(j),'.tif']); 76 | end 77 | 78 | % input the test image files 79 | stack = teststack; 80 | name = [place,'/data/test/']; 81 | for j = 1:size(stack,3) 82 | maxs = reshape(max(max(stack,[],2),[],1),[1,size(stack,3)]); 83 | temp = uint8(256*stack(:,:,j)/maxs(j)); 84 | imwrite(temp, [name,num2str(j),'.tif']); 85 | end 86 | 87 | % change manual to i slices single 256*256 tiff 88 | stack = uint8(255*manualmat); 89 | name = [place,'/data/train/label/']; 90 | for j = 1:num 91 | imwrite(stack(:,:,j), [name,num2str(j),'.tif']); 92 | end 93 | 94 | % after unet 95 | k = imread('/Users/pan/Desktop/unet/results/0.jpg'); 96 | for i = 1:256 97 | for j = 1:256 98 | k2(i,j) = k(2*i,2*j); 99 | end 100 | end 101 | figure;imshow(k2); -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/README.txt: -------------------------------------------------------------------------------- 1 | Last update: 2009-07-28. by Hanchuan Peng 2 | 3 | This directory contains a Matlab toolbox to read and write files with 4 | some formats defined/supported by V3D software (penglab.janelia.org). 5 | 6 | Since some of the functions are mex functions, you may need to run the 7 | following command to generate the mex function for your machine (assuming 8 | you have mex compiling setup in your Matlab): 9 | 10 | >> makeosmex_rawfile_io 11 | 12 | The following is a simple explanation of the interface of functions, both 13 | mex functions and plain Matlab .m functions. 14 | 15 | load_v3d_raw_img_file: load the .raw, .tiff image stacks used in V3D (depending on 16 | file extension, the program automatically determine the file type) 17 | load_v3d_marker_file: load the .marker file 18 | load_v3d_apo_file: load the .apo files (point cloud files) 19 | load_v3d_pointcloud_file: load the point cloud files used in V3D (an overloading 20 | function provided for convenience) 21 | load_v3d_swc_file: load the .swc file (for neurons or other graphs) 22 | load_v3d_neuron_file: load the neuron files in the .swc format (an overloading function 23 | provided for convenience) 24 | 25 | save_v3d_raw_img_file: save the .raw, .tiff image stacks used in V3D (depending on 26 | file extension, the program automatically determine the file type) 27 | save_v3d_marker_file: save the .marker file 28 | save_v3d_apo_file: save the .apo files (point cloud files) 29 | save_v3d_pointcloud_file: save the point cloud files used in V3D (an overloading 30 | function provided for convenience) 31 | save_v3d_swc_file: save the .swc file (for neurons or other graphs) 32 | 33 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/basic_memory.h: -------------------------------------------------------------------------------- 1 | /* basic_memory.h 2 | Some basic memory functions for applications. 3 | 4 | by Hanchuan Peng 5 | 2007-02-16: separated from the original "basic_func.h" so that only include the memory functions. Note that 6 | the interface functions have been rewritten so that they only have one template function without 7 | type conversion. Also change the return type from "int" to "bool", so that they are clearer. 8 | 9 | 2007-02-16: Because I removed all the type conversion in the "new*" functions, an explicit copying function 10 | from a type such as "unsigned char" to "double" is needed. Thus I added a few often-needed wrappers 11 | for these EXPLICIT conversions. These functions are named using "copy1dMem*". 12 | 13 | */ 14 | 15 | #ifndef __BASIC_MEMORY_H__ 16 | #define __BASIC_MEMORY_H__ 17 | 18 | template bool new2dpointer(T ** & p, long sz0, long sz1, const T * p1d); 19 | template void delete2dpointer(T ** & p, long sz0, long sz1); 20 | 21 | template bool new3dpointer(T *** & p, long sz0, long sz1, long sz2, const T * p1d); 22 | template void delete3dpointer(T *** & p, long sz0, long sz1, long sz2); 23 | 24 | template bool new4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3, const T * p1d); 25 | template void delete4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3); 26 | 27 | template bool copy1dMem(T * &p, long len, const char * p1d); 28 | template bool copy1dMem(T * &p, long len, const unsigned char * p1d); 29 | template bool copy1dMem(T * &p, long len, const int * p1d); 30 | template bool copy1dMem(T * &p, long len, const unsigned int * p1d); 31 | template bool copy1dMem(T * &p, long len, const short int * p1d); 32 | template bool copy1dMem(T * &p, long len, const unsigned short int * p1d); 33 | template bool copy1dMem(T * &p, long len, const long * p1d); 34 | template bool copy1dMem(T * &p, long len, const unsigned long * p1d); 35 | template bool copy1dMem(T * &p, long len, const float * p1d); 36 | template bool copy1dMem(T * &p, long len, const double * p1d); 37 | 38 | 39 | /* 40 | template int new3dpointer(T *** & p, long sz0, long sz1, long sz2, unsigned char * p1d); 41 | template int new3dpointer(T *** & p, long sz0, long sz1, long sz2, double * p1d); 42 | template int new3dpointer(T *** & p, long sz0, long sz1, long sz2, float * p1d); 43 | //template int new3dpointer(T *** & p, long sz0, long sz1, long sz2, T * p1d); 44 | //template int new3dpointer(double *** & p, long sz0, long sz1, long sz2, T * p1d); 45 | template void delete3dpointer(T *** & p, long sz0, long sz1, long sz2); 46 | 47 | template int new4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3, unsigned char * p1d); 48 | template int new4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3, double * p1d); 49 | template int new4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3, float * p1d); 50 | //template int new4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3, T * p1d); 51 | template void delete4dpointer(T **** & p, long sz0, long sz1, long sz2, long sz3); 52 | */ 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/checkMachineEndian.cpp: -------------------------------------------------------------------------------- 1 | //checkMachineEndian.cpp 2 | //by Hanchuan Peng 3 | //2008-01-04: copy and paste the code in the stackutil.cpp so that everywhere is consistent 4 | // 5 | 6 | #include 7 | 8 | char checkMachineEndian() 9 | { 10 | char e='N'; //for unknown endianness 11 | 12 | long int a=0x44332211; 13 | unsigned char * p = (unsigned char *)&a; 14 | if ((*p==0x11) && (*(p+1)==0x22) && (*(p+2)==0x33) && (*(p+3)==0x44)) 15 | e = 'L'; 16 | else if ((*p==0x44) && (*(p+1)==0x33) && (*(p+2)==0x22) && (*(p+3)==0x11)) 17 | e = 'B'; 18 | else if ((*p==0x22) && (*(p+1)==0x11) && (*(p+2)==0x44) && (*(p+3)==0x33)) 19 | e = 'M'; 20 | else 21 | e = 'N'; 22 | 23 | //printf("[%c] \n", e); 24 | return e; 25 | } 26 | 27 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 28 | { 29 | if (nrhs>=1) mexErrMsgTxt("Usage: endianCode = checkMachineEndian()"); 30 | 31 | char output_buf[2]; 32 | output_buf[1]='\0'; 33 | output_buf[0]=checkMachineEndian(); 34 | plhs[0] = mxCreateString(output_buf); 35 | } 36 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/elementmexheader.h: -------------------------------------------------------------------------------- 1 | //========================================================= 2 | // 3 | //This is a common header for mex functions 4 | // 5 | //Disclaimer: The author of program is Hanchuan Peng 6 | // at and . 7 | // 8 | //The CopyRight is reserved by the author. 9 | // 10 | //Last modification: Aug/19/2002 11 | //Last modification: Jan 2, 2006 (adapted to the new Powerbook) 12 | //Last modification: Jan 31, 2008 (adapted to the new MacBook Pro) 13 | //Last update: 2008-08-01 14 | //======================================================== 15 | // 16 | 17 | #ifndef __ELEMENTARY_INCLUDE_H_ 18 | #define __ELEMENTARY_INCLUDE_H_ 19 | 20 | //#include 21 | //#include "c:\matlabr12\extern\include\mex.h" 22 | //#include "/usr/local/matlab/extern/include/mex.h" 23 | 24 | /* 25 | #include "/usr/common/pkg/usg/matlab/6.1/extern/include/mex.h" 26 | #include "/usr/common/pkg/usg/matlab/6.1/extern/include/matrix.h" 27 | */ 28 | 29 | /* 30 | #include "c:\math\matlab6p1\extern\include\mex.h" 31 | #include "c:\math\matlab6p1\extern\include\matrix.h" 32 | */ 33 | 34 | //#include "/Applications/MATLAB74/extern/include/mex.h" 35 | //#include "/Applications/MATLAB74/extern/include/matrix.h" 36 | 37 | #include "mex.h" 38 | #include "matrix.h" 39 | 40 | #define BYTE signed char 41 | #define UBYTE unsigned char 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/loadRaw2Stack.m: -------------------------------------------------------------------------------- 1 | function img = loadRaw2Stack(filename, dfactor, b_readThumbNail, b_readMiddleFrameOnly) 2 | %function img = loadRaw2Stack(filename, dfactor, b_readThumbNail, b_readMiddleFrameOnly) 3 | % 4 | % Load raw format generated by Hanchuan Peng as a stack. 5 | % This function is a wrapper to call the actual loadRaw2Stack_c function. 6 | % 7 | % Note: the old .m function with the same name is no longer used. It was 8 | % stored as the .nouse file. 9 | % 10 | % by Hanchuan Peng 11 | % 2006-05-10 12 | % 2007-08-19: add two new parameters about thumb nails and 13 | % middle-frame-only 14 | % 15 | % Note: as of 07/08/19, the b_readThumbNail and b_readMiddleFrameOnly are 16 | % only valid for LSM files. 17 | % 18 | % 2008-08-22: add dfactor to downscale the intensity for 16 bits *tif* images 19 | 20 | if nargin<1, 21 | help loadRaw2Stack; 22 | error('Usage: img = loadRaw2Stack(filename, dfactor, b_readThumbNail, b_readMiddleFrameOnly)'); 23 | end; 24 | 25 | if exist(filename, 'file')==0, 26 | error('You have specified a file which does not exist.'); 27 | end; 28 | 29 | if ~exist('dfactor', 'var'), 30 | dfactor = 0; 31 | end; 32 | 33 | if ~exist('b_readThumbNail', 'var'), 34 | b_readThumbNail = 0; 35 | end; 36 | 37 | if ~exist('b_readMiddleFrameOnly', 'var'), 38 | b_readMiddleFrameOnly = 0; 39 | end; 40 | 41 | 42 | img = squeeze(loadRaw2Stack_c(filename, dfactor, b_readThumbNail, b_readMiddleFrameOnly)); 43 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/load_v3d_apo_file.m: -------------------------------------------------------------------------------- 1 | function m_struct = load_v3d_apo_file(filename) 2 | %function m_struct = load_v3d_apo_file(filename) 3 | % 4 | % Load the .apo point cloud format data file used in V3D 5 | % 6 | % m_struct will consist of point cloud coordinates and other information 7 | % (e.g. name/comments/types/shape) 8 | % 9 | % V3D website: see software page of http://penglab.janelia.org 10 | % 11 | % by Hanchuan Peng 12 | % 20090724 13 | 14 | 15 | m_struct = load_v3d_pointcloud_file(filename); 16 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/load_v3d_marker_file.m: -------------------------------------------------------------------------------- 1 | function m_struct = load_v3d_marker_file(filename) 2 | %function m_struct = load_v3d_marker_file(filename) 3 | % 4 | % Load the .marker format data file used in V3D 5 | % 6 | % m_struct will consist of marker coordinates and name/comments/types/shape 7 | % 8 | % V3D website: see software page of http://penglab.janelia.org 9 | % 10 | % by Hanchuan Peng 11 | % 20090723 12 | 13 | m_struct = []; 14 | 15 | L = loadfilelist(filename); 16 | 17 | k = 0; % k is the real counter of markers 18 | for i=1:length(L), 19 | curline = deblank(L{i}); 20 | if isempty(curline), 21 | continue; 22 | end; 23 | 24 | if (curline(1)=='#' | curline(1)=='x' | curline(1)=='X') 25 | continue; 26 | end; 27 | 28 | ipos = find(curline==','); 29 | cnt = length(ipos)+1; 30 | if (cnt<3), 31 | continue; 32 | end; 33 | 34 | %% get all segments 35 | segs = []; 36 | segs{1} = curline(1:ipos(1)-1); 37 | for j=2:cnt-1, 38 | segs{j} = curline(ipos(j-1)+1:ipos(j)-1); 39 | end; 40 | segs{j+1} = curline(ipos(cnt-1)+1:end); 41 | 42 | %% now assign values 43 | S.x = str2num(segs{1}); 44 | S.y = str2num(segs{2}); 45 | S.z = str2num(segs{3}); 46 | 47 | S.radius = 0; 48 | S.shape = 1; 49 | S.name = ''; 50 | S.comment = ''; 51 | 52 | if (cnt>=4), S.radius = str2num(segs{4}); end; 53 | if (cnt>=5), S.shape = str2num(segs{5}); end; 54 | if (cnt>=6), S.name = segs{6}; end; 55 | if (cnt>=7), S.comment = segs{7}; end; 56 | 57 | %% now assign m_struct 58 | k = k+1; 59 | m_struct{k} = S; 60 | 61 | end; 62 | 63 | return; 64 | 65 | 66 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/load_v3d_neuron_file.m: -------------------------------------------------------------------------------- 1 | function a = load_v3d_neuron_file(filename, b_minusFirst) 2 | %function a = load_v3d_neuron_file(filename, b_minusFirst) 3 | % Load the swc file as a neuron structure 4 | % by Hanchuan Peng 5 | % 070726 6 | % 070809: I notice the majority of neuron swc files have their soma have 7 | % the corredinates (0,0,0), but there are still exceptions. Thus I subtract 8 | % the soma coordinate to assure any neurons have the same origin. 9 | % 080513: add a b_minusFirst flag 10 | % 0904: add a get first 7 columns check 11 | % 090415: add a deblank check 12 | 13 | if nargin<2, 14 | b_minusFirst=0; 15 | end; 16 | 17 | L = loadfilelist(filename); 18 | a = zeros(length(L), 7); 19 | 20 | k=0; 21 | for i=1:length(L), 22 | if isempty(deblank(L{i})), 23 | continue; 24 | end; 25 | if (L{i}(1)=='#'), 26 | continue; 27 | end; 28 | 29 | k=k+1; 30 | tmp = str2num(L{i}); 31 | a(k,:) = tmp(1:7); 32 | end; 33 | 34 | a = a(1:k,:); %%remove the non-used lines 35 | 36 | %make sure all the origin (neuron soma) will be 0 37 | if b_minusFirst, 38 | a(:,3:5) = a(:,3:5) - repmat(a(1,3:5), size(a,1), 1); 39 | end; 40 | 41 | return; 42 | 43 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/load_v3d_pointcloud_file.m: -------------------------------------------------------------------------------- 1 | function m_struct = load_v3d_pointcloud_file(filename) 2 | %function m_struct = load_v3d_pointcloud_file(filename) 3 | % 4 | % Load the .apo point cloud format data file used in V3D 5 | % 6 | % m_struct will consist of point cloud coordinates and other information 7 | % (e.g. name/comments/types/shape) 8 | % 9 | % V3D website: see software page of http://penglab.janelia.org 10 | % 11 | % by Hanchuan Peng 12 | % 20090724 13 | 14 | m_struct = []; 15 | 16 | L = loadfilelist(filename); 17 | 18 | k = 0; % k is the real counter of markers 19 | for i=1:length(L), 20 | curline = deblank(L{i}); 21 | if isempty(curline), 22 | continue; 23 | end; 24 | 25 | if (curline(1)=='#') 26 | continue; 27 | end; 28 | 29 | ipos = find(curline==','); 30 | cnt = length(ipos)+1; 31 | if (cnt<12), 32 | continue; 33 | end; 34 | 35 | %% get all segments 36 | segs = []; 37 | segs{1} = curline(1:ipos(1)-1); 38 | for j=2:cnt-1, 39 | segs{j} = curline(ipos(j-1)+1:ipos(j)-1); 40 | end; 41 | segs{j+1} = curline(ipos(cnt-1)+1:end); 42 | 43 | %% now assign values 44 | 45 | S.n = round(str2num(segs{1})); 46 | 47 | S.orderinfo = ''; 48 | S.name = ''; 49 | S.comment = ''; 50 | S.z = -1; 51 | S.x = -1; 52 | S.y = -1; 53 | S.pixmax = 0; 54 | S.intensity = 0; 55 | S.sdev = 0; 56 | S.volsize = 0; 57 | S.mass = 0; 58 | rr = rand(3,1); 59 | rr = rr./sqrt(sum(rr.*rr)).*255; 60 | S.color.r = rr(1); 61 | S.color.g = rr(2); 62 | S.color.b = rr(3); 63 | 64 | if (cnt>=2), S.orderinfo = segs{2}; end; 65 | if (cnt>=3), S.name = segs{3}; end; 66 | if (cnt>=4), S.comment = segs{4}; end; 67 | if (cnt>=5), S.z = str2num(segs{5}); end; 68 | if (cnt>=6), S.x = str2num(segs{6}); end; 69 | if (cnt>=7), S.y = str2num(segs{7}); end; 70 | if (cnt>=8), S.pixmax = str2num(segs{8}); end; 71 | if (cnt>=9), S.intensity = str2num(segs{9}); end; 72 | if (cnt>=10), S.sdev = str2num(segs{10}); end; 73 | if (cnt>=11), S.volsize = str2num(segs{11}); end; 74 | if (cnt>=12), S.mass = str2num(segs{12}); end; 75 | if (cnt>=16), S.color.r = round(str2num(segs{16})); end; 76 | if (cnt>=17), S.color.g = round(str2num(segs{17})); end; 77 | if (cnt>=18), S.color.b = round(str2num(segs{18})); end; 78 | 79 | 80 | %% now assign m_struct 81 | k = k+1; 82 | m_struct{k} = S; 83 | 84 | end; 85 | 86 | return; 87 | 88 | 89 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/load_v3d_raw_img_file.m: -------------------------------------------------------------------------------- 1 | function img = load_v3d_raw_img_file(filename) 2 | %function img = load_v3d_raw_img_file(filename) 3 | % 4 | % Load the .RAW or .TIF or (even .LSM) image stack files that are supported by V3D 5 | % 6 | % 7 | % V3D website: see software page of http://penglab.janelia.org 8 | % 9 | % by Hanchuan Peng 10 | % 20090724 11 | 12 | img = loadRaw2Stack(filename); 13 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/load_v3d_swc_file.m: -------------------------------------------------------------------------------- 1 | function a = load_v3d_swc_file(filename, b_minusFirst) 2 | %function a = load_v3d_swc_file(filename, b_minusFirst) 3 | % Load the swc file as a neuron structure 4 | % by Hanchuan Peng 5 | % 6 | % an overaloading function for convenience 7 | % 8 | % 2009-07-24 9 | 10 | if nargin<2, 11 | b_minusFirst=0; 12 | end; 13 | 14 | a = load_v3d_neuron_file(filename, b_minusFirst); 15 | 16 | return; 17 | 18 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/loadfilelist.m: -------------------------------------------------------------------------------- 1 | function filelist = loadfilelist(filename) 2 | % filelist = loadfilelist(filename) 3 | % read a plain text file for all image names. One line is an image name. 4 | % 5 | % By Hanchuan Peng 6 | % Jan,2001 7 | % June, 2005. Fix the non-return value bug 8 | 9 | filelist = []; 10 | fid = fopen(filename); 11 | if fid==-1, 12 | disp(['Error to open the file : ' filename]); 13 | return; 14 | else 15 | i=1; 16 | while 1 17 | tline = fgetl(fid); 18 | if ~ischar(tline), break; end; 19 | filelist{i} = deblank(tline); 20 | i = i+1; 21 | end; 22 | end; 23 | fclose(fid); 24 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/makeosmex_rawfile_io.m: -------------------------------------------------------------------------------- 1 | %% This file is generated in case I forget the right way to compile next 2 | %% time, :-) 3 | %% 4 | %%by Hanchuan Peng 5 | %% 2007-03-06 6 | % last update: 090722: by Hanchuan Peng. This makes it easire to compile all mex files under this directory 7 | 8 | mex loadRaw2Stack_c.cpp mg_image_lib.cpp mg_utilities.cpp -ltiff 9 | mex saveStack2File_c.cpp mg_image_lib.cpp mg_utilities.cpp -ltiff 10 | 11 | mex checkMachineEndian.cpp 12 | 13 | 14 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/mg_utilities.h: -------------------------------------------------------------------------------- 1 | /*****************************************************************************************\ 2 | * * 3 | * Utilities for allocating memory, opening files, and processing command line arguments * 4 | * * 5 | * Author: Gene Myers * 6 | * Date : October 2005 * 7 | * * 8 | \*****************************************************************************************/ 9 | 10 | /* changed the include file name by PHC 060816*/ 11 | 12 | #ifndef MG_SR_UTILITIES 13 | 14 | #define MG_SR_UTILITIES 15 | 16 | #include 17 | 18 | #define ASCII 128 19 | 20 | /* The usual protected allocation and file opening routines. */ 21 | 22 | void *Guarded_Malloc(int size, char *routine); 23 | void *Guarded_Realloc(void *array, int size, char *routine); 24 | char *Guarded_Strdup(char *string, char *routine); 25 | FILE *Guarded_Fopen(char *name, char *options, char *routine); 26 | 27 | /* The structure of the command line to be interpreted is specified in an array of 28 | 'Arg_Spec' records the last of which is {NULL,NULL,NULL} signalling the end of the 29 | spec. An arg spec consists of three string fields that are described in detail in 30 | Appendix A. */ 31 | 32 | typedef struct 33 | { char *name; // lookup name and command line string if an option 34 | char *type; // syntax and form of the argument 35 | char *defval; // default value (if any) 36 | } Arg_Spec; 37 | 38 | /* Process the command line according to 'spec'. All arguments are parsed and checked. 39 | All required argument must be present. Any failure results in an error message and 40 | the end of execution. One tricky thing here is that 'spec' itself is interpreted, 41 | so an invalid spec will also produce an error message. Be sure to debug the spec! */ 42 | 43 | void Process_Arguments(int argc, char *argv[], Arg_Spec *spec); 44 | 45 | /* Once the command line has been parsed you can get the value of any argument by calling 46 | the appropriately typed 'Get' routine with the name of the argument. You presumably 47 | know the type since you wrote the spec. If an argument is an iterator then you must 48 | further suppply the 'Get' call with the index of the instance you want, where the numbering 49 | starts at 1. To know how many instances there are call Argument_Cardinality. For non-iterative 50 | arguments this routine returns 1 if the argument has a value, and 0 if it does not. 51 | Finally, you can get the program name with Program_Name. */ 52 | 53 | char *Program_Name(); 54 | 55 | int Argument_Cardinality(char *name); 56 | 57 | int Get_Int_Arg (char *name, ...); 58 | double Get_Double_Arg(char *name, ...); 59 | char *Get_String_Arg(char *name, ...); 60 | 61 | /* There may be constraints among the arguments that are not captured by the spec that 62 | you explictly check after the call to Process_Args. If you detect an error and wish 63 | to print out a usage message, a call to Print_Argument_Usage will do so on the file 'file'. */ 64 | 65 | void Print_Argument_Usage(FILE *file); 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/saveStack2File_c.cpp: -------------------------------------------------------------------------------- 1 | /* Save the stack to either tif or raw (Hanchuan Peng's raw) file. 2 | 3 | by Hanchuan Peng 4 | Updated 060828: 5 | mex -c mg_utilities.c 6 | mex -c mg_image_lib.c 7 | mex loadRaw2Stack_c.cpp mg_image_lib.o mg_utilities.o -v -ltiff 8 | 9 | Updated: 070426: add uint16 and single writing support 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include "stackutil.cpp" 16 | 17 | /* use the C_INTERFACE to control if compile the Matlab version interface to read the stacks. */ 18 | 19 | //#define C_INTERFACE 1 20 | 21 | #ifdef C_INTERFACE 22 | 23 | /* main program for C interface */ 24 | 25 | void printHelp (); 26 | void printHelp() 27 | { 28 | printf("\nUsage: saveStack2File_c -i \n"); 29 | printf("\t -i .raw file containing the stack generated using saveStack2Raw.m program.\n"); 30 | printf ("\t [-h] print this message.\n"); 31 | return; 32 | } 33 | 34 | #include 35 | extern char *optarg; 36 | extern int optind, opterr; 37 | 38 | int main (int argc, char *argv[]) 39 | { 40 | if (argc <= 1) 41 | { 42 | printHelp (); 43 | return 0; 44 | } 45 | 46 | /* Read arguments */ 47 | 48 | char *input_dfile = NULL; 49 | 50 | int c; 51 | static char optstring[] = "hi:"; 52 | opterr = 0; 53 | while ((c = getopt (argc, argv, optstring)) != -1) 54 | { 55 | switch (c) 56 | { 57 | case 'h': 58 | printHelp (); 59 | return 0; 60 | break; 61 | 62 | case 'i': 63 | /* fprintf(stderr,"[%s]-> ",optarg); */ 64 | if (strcmp (optarg, "(null)") == 0 || optarg[0] == '-') 65 | { 66 | fprintf (stderr, 67 | "Found illegal or NULL parameter for the option -i.\n"); 68 | return 1; 69 | } 70 | input_dfile = optarg; 71 | break; 72 | 73 | case '?': 74 | fprintf (stderr, "Unknown option `-%c' or incomplete argument lists.\n", optopt); 75 | return 0; 76 | 77 | /* default: abort (); */ 78 | } 79 | } 80 | 81 | if (optind < argc) 82 | printf ("Stop parsing arguments list. Left off at %s\n", argv[optind]); 83 | 84 | /* Read file and display some information. */ 85 | 86 | unsigned char * img = 0; /* note that this variable must be initialized as NULL. */ 87 | long * sz = 0; /* note that this variable must be initialized as NULL. */ 88 | int datatype = 0; 89 | 90 | char * curFileSurfix = getSurfix(input_dfile); 91 | printf("The current input file has the surfix [%s]\n", curFileSurfix); 92 | if (strcasecmp(curFileSurfix, "tif")==0 || strcasecmp(curFileSurfix, "tiff")==0) //read tiff stacks 93 | { 94 | if (loadTif2Stack(input_dfile, img, sz, datatype)) 95 | { 96 | printf("Error happens in TIF file reading. Exit. \n"); 97 | return 1; 98 | } 99 | } 100 | else //then assume it is Hanchuan's RAW format 101 | { 102 | if (loadRaw2Stack(input_dfile, img, sz, datatype)) 103 | { 104 | printf("Error happens in RAW file reading. Exit. \n"); 105 | return 1; 106 | } 107 | } 108 | 109 | 110 | switch (datatype) 111 | { 112 | case 1: 113 | printf("The data type is 8-bit integer.\n"); 114 | printf("The size of this image stack is [%d %d %d %d]\n", sz[0], sz[1], sz[2], sz[3]); 115 | break; 116 | 117 | case 2: 118 | printf("The data type is 16-bit integer.\n"); 119 | printf("The size of this image stack is [%d %d %d %d]\n", sz[0], sz[1], sz[2], sz[3]); 120 | break; 121 | 122 | case 4: 123 | printf("The data type is 32-bit float/long/int.\n"); 124 | printf("The size of this image stack is [%d %d %d %d]\n", sz[0], sz[1], sz[2], sz[3]); 125 | break; 126 | 127 | default: 128 | printf("Something wrong with the program, -- should NOT display this message at all. Check your program. \n"); 129 | if (img) {delete [] img; img=0;} 130 | if (sz) {delete []sz; sz=0;} 131 | return 1; 132 | } 133 | 134 | /* clean all workspace variables */ 135 | 136 | if (img) {delete [] img; img=0;} 137 | if (sz) {delete []sz; sz=0;} 138 | 139 | return 0; 140 | } 141 | 142 | #else 143 | 144 | #include "elementmexheader.h" 145 | 146 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 147 | { 148 | if (nrhs!=2) mexErrMsgTxt("Usage: saveStack2File_c(img, infilename)"); 149 | if (!mxIsChar(prhs[1])) mexErrMsgTxt("The second input argument must be String/CHAR."); 150 | if (!mxIsUint8(prhs[0]) && !mxIsUint16(prhs[0]) && !mxIsSingle(prhs[0])) mexErrMsgTxt("The first input argument must be UINT8 / UINt16 or SINGLE."); 151 | 152 | long i,j,k,c; 153 | 154 | //handle the image data 155 | long sz[4]; 156 | unsigned char * img = (unsigned char *)mxGetData(prhs[0]); 157 | int * imgsz = (int *)mxGetDimensions(prhs[0]); 158 | int imgdims = mxGetNumberOfDimensions(prhs[0]); 159 | 160 | if (imgdims>4) 161 | { 162 | printf("Number of dimensions = %d (bigger than 4, -- only use the first 4 dimensions).\n", imgdims); 163 | } 164 | else if (imgdims<4) 165 | { 166 | printf("Number of dimensions = %d (smaller than 4, -- the unappearing dimensions are set as 1).\n", imgdims); 167 | } 168 | 169 | for (i=0;i<4;i++) sz[i] = 1; //set default 170 | for (i=0;i<((imgdims<4)?imgdims:4); i++) 171 | sz[i] = imgsz[i]; 172 | printf("Save dims: %d %d %d %d\n", sz[0], sz[1], sz[2], sz[3]); 173 | 174 | /* Allocate enough memory to hold the converted string. */ 175 | 176 | int buflen = mxGetNumberOfElements(prhs[1]) + 1; 177 | char * buf = new char [buflen]; 178 | if (mxGetString(prhs[1], buf, buflen) != 0) 179 | mexErrMsgTxt("Could not convert string data."); 180 | 181 | /* File write */ //update on 070426 182 | int datatype=1; //default is uint8 183 | if (mxIsUint8(prhs[0])) datatype=1; 184 | else if (mxIsUint16(prhs[0])) datatype=2; 185 | else datatype=4; 186 | 187 | char * curFileSurfix = getSurfix(buf); 188 | printf("The current input file has the surfix [%s]\n", curFileSurfix); 189 | if (strcasecmp(curFileSurfix, "tif")==0 || strcasecmp(curFileSurfix, "tiff")==0) //read tiff stacks 190 | { 191 | if (saveStack2Tif(buf, img, sz, datatype)) 192 | { 193 | printf("Error happens in TIF file reading. Exit. \n"); 194 | if (buf) {delete []buf; buf=0;} 195 | return; 196 | } 197 | } 198 | else //then assume it is Hanchuan's RAW format 199 | { 200 | if (saveStack2Raw(buf, img, sz, datatype)) 201 | { 202 | printf("Error happens in RAW file reading. Exit. \n"); 203 | if (buf) {delete []buf; buf=0;} 204 | return; 205 | } 206 | } 207 | 208 | 209 | /* clean all workspace variables */ 210 | 211 | if (buf) {delete []buf; buf=0;} 212 | //if (imgsz) {delete []imgsz; imgsz=0;} 213 | 214 | return; 215 | } 216 | 217 | #endif 218 | 219 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/save_v3d_apo_file.m: -------------------------------------------------------------------------------- 1 | function save_v3d_apo_file(m_struct, filename) 2 | %function save_v3d_apo_file(m_struct, filename) 3 | % 4 | % Save the .apo point cloud format data file used in V3D 5 | % 6 | % m_struct will consist of point cloud coordinates and other information 7 | % (e.g. name/comments/types/shape) 8 | % 9 | % V3D website: see software page of http://penglab.janelia.org 10 | % 11 | % by Hanchuan Peng 12 | % 20090724 13 | 14 | 15 | save_v3d_pointcloud_file(m_struct, filename); 16 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/save_v3d_marker_file.m: -------------------------------------------------------------------------------- 1 | function save_v3d_marker_file(m_struct, filename) 2 | %function save_v3d_marker_file(m_struct, filename) 3 | % 4 | % Save the .marker format data file used in V3D 5 | % 6 | % m_struct will consist of marker coordinates and name/comments/types/shape 7 | % 8 | % V3D website: see software page of http://penglab.janelia.org 9 | % 10 | % by Hanchuan Peng 11 | % 20090723 12 | 13 | fp = fopen(filename, 'w'); 14 | if (fp<0), 15 | disp('Fail to open the file to save V3D .marker format data'); 16 | return; 17 | end; 18 | 19 | fprintf(fp, '#x, y, z, radius, shape, name, comment\n'); 20 | 21 | for i=1:length(m_struct), 22 | S = m_struct{i}; 23 | fprintf(fp, '%5.3f, %5.3f, %5.3f, %d, %d, %s, %s\n', ... 24 | S.x, ... 25 | S.y, ... 26 | S.z, ... 27 | S.radius, ... 28 | S.shape, ... 29 | trimmed_str(S.name, 99), ... 30 | trimmed_str(S.comment, 99)); 31 | end; 32 | 33 | fclose(fp); 34 | 35 | return; 36 | 37 | 38 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/save_v3d_pointcloud_file.m: -------------------------------------------------------------------------------- 1 | function save_v3d_pointcloud_file(m_struct, filename) 2 | %function save_v3d_pointcloud_file(m_struct, filename) 3 | % 4 | % Save the .apo point cloud format data file used in V3D 5 | % 6 | % m_struct will consist of point cloud coordinates and other information 7 | % (e.g. name/comments/types/shape) 8 | % 9 | % V3D website: see software page of http://penglab.janelia.org 10 | % 11 | % by Hanchuan Peng 12 | % 20090724 13 | 14 | fp = fopen(filename, 'w'); 15 | if (fp<0), 16 | disp('Fail to open the file to save V3D pointcloud (.apo) format data'); 17 | return; 18 | end; 19 | 20 | fprintf(fp, ... 21 | ['#no, order_info, name, comment, z, x, y, ' ... 22 | 'max_intensity, mean_intensity, sdev_intensity, ' ... 23 | 'rgn size (#voxels), mass, reserved_anno_1, reserved_anno_2, ' ... 24 | 'reserved_anno_3, color_red, color_green, color_blue\n']); 25 | 26 | for i=1:length(m_struct), 27 | S = m_struct{i}; 28 | fprintf(fp, '%d, %s, %s, %s, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f, %s, %s, %s, %d, %d, %d\n', ... 29 | S.n, ... 30 | trimmed_str(S.orderinfo, 99), ... 31 | trimmed_str(S.name, 99), ... 32 | trimmed_str(S.comment, 99), ... 33 | S.z, ... 34 | S.x, ... 35 | S.y, ... 36 | S.pixmax, ... 37 | S.intensity, ... 38 | S.sdev, ... 39 | S.volsize, ... 40 | S.mass, ... 41 | '', ... 42 | '', ... 43 | '', ... 44 | S.color.r, ... 45 | S.color.g, ... 46 | S.color.b); 47 | end; 48 | 49 | fclose(fp); 50 | 51 | return; 52 | 53 | 54 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/save_v3d_raw_img_file.m: -------------------------------------------------------------------------------- 1 | function save_v3d_raw_img_file(img, filename) 2 | %function save_v3d_raw_img_file(img, filename) 3 | % 4 | % Write an image stack (4D array of UINT8, UINT16, or SINGLE type) to 5 | % the .RAW or .TIF image stack files (depending on the suffix given) that are supported by V3D 6 | % 7 | % 8 | % V3D website: see software page of http://penglab.janelia.org 9 | % 10 | % by Hanchuan Peng 11 | % 20090724 12 | 13 | saveStack2File_c(img, filename); 14 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/save_v3d_swc_file.m: -------------------------------------------------------------------------------- 1 | function save_v3d_swc_file(tt, outfilename) 2 | %function save_v3d_swc_file(tt, outfilename) 3 | % write a swc formatted variable to a file 4 | % 5 | % by Hanchuan Peng 6 | % 2008-05-15 7 | % 8 | 9 | if isempty(tt), 10 | return; 11 | end; 12 | 13 | if size(tt,2)<7, 14 | error('The first variable must have at least 7 columns.'), 15 | end; 16 | 17 | f = fopen(outfilename, 'wt'); 18 | if f<=0, 19 | error('Fail to open file to write'); 20 | end; 21 | 22 | for i=1:size(tt,1), 23 | fprintf(f, '%d %d %5.3f %5.3f %5.3f %5.3f %d\n', tt(i,1), tt(i,2), tt(i,3), tt(i,4), tt(i,5), tt(i,6), tt(i,7)); 24 | end; 25 | 26 | fclose(f); 27 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/savefilelist.m: -------------------------------------------------------------------------------- 1 | function savefilelist(filelist, filename) 2 | % savefilelist(filelist, filename) 3 | % save a cell array of strings as a plain text file. 4 | % 5 | % By Hanchuan Peng 6 | % June,2005 7 | 8 | if ~isa(filelist, 'cell'), 9 | error('The first input is not a cell array'); 10 | end; 11 | 12 | fid = fopen(filename, 'wt'); 13 | if fid==-1, 14 | disp(['Error to open the file : ' filename]); 15 | return; 16 | else 17 | for i=1:length(filelist), 18 | if isa(filelist{i}, 'char'), 19 | fprintf(fid, '%s\n', filelist{i}); 20 | end; 21 | end; 22 | fclose(fid); 23 | end; 24 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/stackutil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * stackutil.h 3 | * 4 | * 5 | * Created by Hanchuan Peng on 7/31/06. 6 | * Copyright 2006 __Hanchuan Peng__. All rights reserved. 7 | * 8 | * Updated: 060816: add tif support 9 | * 060828: add surfix extraction function here 10 | * 060920: add the 2-byte raw support for compatibility 11 | * 070214: add two simple interface to read any file formats supported (raw or tif) based on the surfix of filename 12 | * 070806: add LSM file reading functions 13 | * 070819: add LSM thumbnail stack reading and the middle-slice-only reading 14 | * 070823: add a more comprehensive function to read either 1 slice (original or thumbnail) or the entire stack (original or thumbnail) from lsm file 15 | * 080213: add functions to read/ single slice/thumbnail from tiff/raw stacks 16 | */ 17 | 18 | #ifndef __STACKUTIL__ 19 | #define __STACKUTIL__ 20 | 21 | extern "C" { 22 | #include "tiffio.h" 23 | }; 24 | 25 | typedef char BIT8_UNIT; 26 | typedef short int BIT16_UNIT; 27 | typedef int BIT32_UNIT; 28 | typedef long BIT64_UNIT; 29 | 30 | int loadRaw2Stack(char * filename, unsigned char * & img, long * & sz, int & datatype); //4-byte raw reading 31 | int saveStack2Raw(const char * filename, const unsigned char * img, const long * sz, int datatype); //4-byte raw writing 32 | 33 | int loadRaw2Stack_2byte(char * filename, unsigned char * & img, long * & sz, int & datatype); 34 | int saveStack2Raw_2byte(const char * filename, const unsigned char * img, const long * sz, int datatype); 35 | 36 | void swap2bytes(void *targetp); 37 | void swap4bytes(void *targetp); 38 | char checkMachineEndian(); 39 | 40 | int loadTif2Stack(char * filename, unsigned char * & img, long * & sz, int & datatype); 41 | int saveStack2Tif(const char * filename, const unsigned char * img, const long * sz, int datatype); 42 | 43 | //the following two functions are the major routines to load LSM file 44 | int loadLsm2Stack_obsolete(char * filename, unsigned char * & img, long * & sz, int & datatype); //070806 45 | int loadLsm2Stack(char * filename, unsigned char * & img, long * & sz, int & datatype); //070806 46 | 47 | //the following three functions are the low-level routines to load LSM file 48 | int read_lsm_slice(TIFF *in, unsigned char * pointer_first_page, long pagepixelnumber, long channelpixelnumber, int datatype); 49 | int read_lsm_slice_strip(TIFF *in, unsigned char * pointer_first_page, long pagepixelnumber, long channelpixelnumber, int datatype); 50 | int read_lsm_slice_tile(TIFF *in, unsigned char * pointer_first_page, long pagepixelnumber, long channelpixelnumber, int datatype); 51 | int loadLsm2Stack_middle(char * filename, unsigned char * & img, long * & sz, int & datatype); //070819 52 | 53 | //read LSM thumbnail. 070819 54 | int loadLsmThumbnail2Stack(char * filename, unsigned char * & img, long * & sz, int & datatype); 55 | int loadLsmThumbnail2Stack_middle(char * filename, unsigned char * & img, long * & sz, int & datatype); 56 | 57 | //a more comprehensive way to read LSM file. 070823 58 | int loadLsmSlice(char * filename, unsigned char * & img, long * & sz, int & datatype, long sliceno, bool b_thumbnail); 59 | 60 | //more comprehensive interfaces to read tiff and raw files. 080213 61 | int loadTifSlice(char * filename, unsigned char * & img, long * & sz, int & datatype, long sliceno, bool b_thumbnail); 62 | int read_tif_slice(TIFF *tif, unsigned char * pointer_first_page, long width, long height); 63 | 64 | int read_tif_slice_strip(TIFF *in, unsigned char * pointer_first_page, long pagepixelnumber, long channelpixelnumber, int datatype); 65 | int read_tif_slice_tile(TIFF *in, unsigned char * pointer_first_page, long pagepixelnumber, long channelpixelnumber, int datatype); 66 | 67 | int loadRawSlice(char * filename, unsigned char * & img, long * & sz, int & datatype, long sliceno, bool b_thumbnail); 68 | int loadRawSlice_2byte(char * filename, unsigned char * & img, long * & sz, int & datatype, long sliceno, bool b_thumbnail); 69 | 70 | // 71 | 72 | char * getSurfix(char *filename); //note that no need to delete the returned pointer as it is actually a location to the "filename" 73 | 74 | bool ensure_file_exists_and_size_not_too_big(char *filename, long sz_thres); 75 | 76 | bool loadImage(char imgSrcFile[], unsigned char *& data1d, long * &sz, int & datatype); //070215 77 | bool saveImage(const char filename[], const unsigned char * data1d, const long * sz, const int datatype); //070214 78 | 79 | #endif 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /v3d_matlab_io_basicdatatype/trimmed_str.m: -------------------------------------------------------------------------------- 1 | function out_str = trimmed_str(in_str, n) 2 | % function out_str = trimmed_str(in_str, n) 3 | % this function is to ensure there are at most n characterz in the str, so 4 | % that later on the .apo and .marker file can be successfully erad in V3D (there is a 5 | % max # character in a line limitation) 6 | % 7 | % by Hanchuan Peng 8 | % 2009-07-25 9 | 10 | if (n<0), n=0; end; 11 | n0 = length(in_str); 12 | if (n0>n), n0=n; end; 13 | out_str = in_str(1:n0); 14 | return; 15 | 16 | -------------------------------------------------------------------------------- /vessel.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/vessel.mat -------------------------------------------------------------------------------- /wrong.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pandolph/Brain_Science_Image_Platform/3f185428cdd58bf0cc36cfcf5f80f3616c11884f/wrong.m --------------------------------------------------------------------------------