[892] | 1 | |
---|
[849] | 2 | % phys_ima: transform several images in phys coordinates on a common pixel grid |
---|
| 3 | %------------------------------------------------------------------------ |
---|
| 4 | % OUTPUT: |
---|
[1166] | 5 | % A_out: cell array of intput images corresponding to the transform of the input images |
---|
[849] | 6 | % Rangx, Rangy; vectors with two elements defining the phys positions of first and last pixels in each direction |
---|
| 7 | % (the same for all the ouput images) |
---|
| 8 | % |
---|
| 9 | % INPUT: |
---|
| 10 | % A: cell array of input images |
---|
| 11 | % XmlData: cell array of structures defining the calibration parameters for each image |
---|
| 12 | % ZIndex: index of the reference plane used to define the phys position in 3D |
---|
[1129] | 13 | % resolution_factor: factor to control the number of pixels of the new image, default value =1 : same nbre of pixels as the original |
---|
| 14 | function [A_out,Rangx,Rangy]=phys_ima(A,XmlData,ZIndex,resolution_factor) |
---|
[849] | 15 | xcorner=[]; |
---|
| 16 | ycorner=[]; |
---|
| 17 | npx=[]; |
---|
| 18 | npy=[]; |
---|
[1166] | 19 | |
---|
[849] | 20 | if isstruct(XmlData) |
---|
| 21 | XmlData={XmlData}; |
---|
| 22 | end |
---|
[1129] | 23 | if ~exist('resolution_factor','var') |
---|
| 24 | resolution_factor=1; |
---|
| 25 | end |
---|
[1166] | 26 | checknumeric=0; |
---|
| 27 | if isnumeric(A) |
---|
| 28 | A={A}; |
---|
| 29 | checknumeric=1; |
---|
| 30 | end |
---|
| 31 | dx=ones(1,numel(A)); |
---|
| 32 | dy=ones(1,numel(A)); |
---|
[849] | 33 | for icell=1:numel(A) |
---|
| 34 | siz=size(A{icell}); |
---|
| 35 | npx=[npx siz(2)]; |
---|
| 36 | npy=[npy siz(1)]; |
---|
[1112] | 37 | Calib{icell}=XmlData{icell}.GeometryCalib; |
---|
| 38 | Slice{icell}=Calib{icell}; |
---|
| 39 | if isfield(XmlData{icell},'Slice') |
---|
| 40 | Slice{icell}=XmlData{icell}.Slice; |
---|
| 41 | end |
---|
[1078] | 42 | coord_x=[0.5 siz(2)-0.5]; |
---|
| 43 | coord_y=[0.5 siz(1)-0.5]; |
---|
| 44 | x_edge=[linspace(coord_x(1),coord_x(end),npx(icell)) coord_x(end)*ones(1,npy(icell))... |
---|
| 45 | linspace(coord_x(end),coord_x(1),npx(icell)) coord_x(1)*ones(1,npy(icell))];%x coordinates of the image edge(four sides) |
---|
| 46 | y_edge=[coord_y(1)*ones(1,npx(icell)) linspace(coord_y(1),coord_y(end),npy(icell))... |
---|
| 47 | coord_y(end)*ones(1,npx(icell)) linspace(coord_y(end),coord_y(1),npy(icell))];%y coordinates of the image edge(four sides) |
---|
[1112] | 48 | [xcorner_new,ycorner_new]=phys_XYZ(Calib{icell},Slice{icell},x_edge,y_edge,ZIndex);%corresponding physical coordinates |
---|
[849] | 49 | dx(icell)=(max(xcorner_new)-min(xcorner_new))/(siz(2)-1); |
---|
| 50 | dy(icell)=(max(ycorner_new)-min(ycorner_new))/(siz(1)-1); |
---|
| 51 | xcorner=[xcorner xcorner_new]; |
---|
| 52 | ycorner=[ycorner ycorner_new]; |
---|
| 53 | end |
---|
| 54 | Rangx(1)=min(xcorner); |
---|
| 55 | Rangx(2)=max(xcorner); |
---|
| 56 | Rangy(2)=min(ycorner); |
---|
| 57 | Rangy(1)=max(ycorner); |
---|
| 58 | test_multi=(max(npx)~=min(npx)) || (max(npy)~=min(npy)); %different image lengths |
---|
[922] | 59 | |
---|
[1129] | 60 | npX=1+round(resolution_factor*(Rangx(2)-Rangx(1))/max(dx));% nbre of pixels in the new image (use the largest resolution max(dx) in the set of images) |
---|
| 61 | npY=1+round(resolution_factor*(Rangy(1)-Rangy(2))/max(dy)); |
---|
[922] | 62 | |
---|
[849] | 63 | x=linspace(Rangx(1),Rangx(2),npX); |
---|
| 64 | y=linspace(Rangy(1),Rangy(2),npY); |
---|
[1078] | 65 | [X,Y]=meshgrid(x,y);%grid in physical coordinates |
---|
[849] | 66 | A_out=cell(1,numel(A)); |
---|
[1078] | 67 | |
---|
[1112] | 68 | for icell=1:numel(A) |
---|
[849] | 69 | % rescaling of the image coordinates without change of the image array |
---|
[1112] | 70 | if strcmp(Calib{icell}.CalibrationType,'rescale') && isequal(Calib,XmlData{1}.GeometryCalib) |
---|
[849] | 71 | A_out{icell}=A{icell};%no transform |
---|
| 72 | Rangx=[0.5 npx-0.5];%image coordiantes of corners |
---|
| 73 | Rangy=[npy-0.5 0.5]; |
---|
[1112] | 74 | [Rangx]=phys_XYZ(Calib{icell},[],Rangx,[0.5 0.5],ZIndex);%case of translations without rotation and quadratic deformation |
---|
| 75 | [~,Rangy]=phys_XYZ(Calib{icell},[],[0.5 0.5],Rangy,ZIndex); |
---|
[972] | 76 | else |
---|
[849] | 77 | % the image needs to be interpolated to the new coordinates |
---|
[1078] | 78 | Z=0; %default |
---|
[1112] | 79 | if isfield(Slice{icell},'SliceCoord')&& size(Slice{icell}.SliceCoord,1)>=ZIndex %.Z= index of plane |
---|
| 80 | SliceCoord=Slice{icell}.SliceCoord(ZIndex,:); |
---|
[1078] | 81 | Z=SliceCoord(3); |
---|
[1112] | 82 | if isfield(Slice{icell}, 'SliceAngle') && size(Slice{icell}.SliceAngle,1)>=ZIndex && ~isequal(Slice{icell}.SliceAngle(ZIndex,:),[0 0 0]) |
---|
| 83 | norm_plane=angle2normal(Slice{icell}.SliceAngle(ZIndex,:)); |
---|
[1078] | 84 | Z=Z-(norm_plane(1)*(X-SliceCoord(1))+norm_plane(2)*(Y-SliceCoord(2)))/norm_plane(3); |
---|
[972] | 85 | end |
---|
[849] | 86 | end |
---|
[922] | 87 | xima=0.5:npx(icell)-0.5;%image coordinates of corners |
---|
| 88 | yima=npy(icell)-0.5:-1:0.5; |
---|
[849] | 89 | [XIMA_init,YIMA_init]=meshgrid(xima,yima);%grid of initial image in px coordinates |
---|
[1112] | 90 | [XIMA,YIMA]=px_XYZ(Calib{icell},Slice{icell},X,Y,Z);% image coordinates for each point in the real |
---|
[849] | 91 | testuint8=isa(A{icell},'uint8'); |
---|
| 92 | testuint16=isa(A{icell},'uint16'); |
---|
[1078] | 93 | if ismatrix(A{icell}) %(B/W images) |
---|
| 94 | A_out{icell}=interp2(XIMA_init,YIMA_init,double(A{icell}),XIMA,YIMA); |
---|
| 95 | elseif ndims(A{icell})==3 |
---|
| 96 | for icolor=1:size(A{icell},3) |
---|
| 97 | A{icell}=double(A{icell}); |
---|
| 98 | A_out{icell}(:,:,icolor)=interp2(XIMA_init,YIMA_init,A{icell}(:,:,icolor),XIMA,YIMA); |
---|
| 99 | end |
---|
| 100 | end |
---|
[849] | 101 | if testuint8 |
---|
| 102 | A_out{icell}=uint8(A_out{icell}); |
---|
| 103 | end |
---|
| 104 | if testuint16 |
---|
| 105 | A_out{icell}=uint16(A_out{icell}); |
---|
[1078] | 106 | end |
---|
[849] | 107 | end |
---|
| 108 | end |
---|
[1166] | 109 | if checknumeric |
---|
| 110 | A_out=A_out{1}; |
---|
| 111 | end |
---|