Comparing 2 different image - matlab

I am trying to compare multiple image using corr2 to see the similarity in correlation.
for i=1:2
first_img = imread(sprintf('%g.jpg',i));
first_size = size(first_img);
size_temp = size(first_size);
max_size = max(size_temp);
if max_size == 3
first_img = rgb2gray(first_img);
first_size = size(first_img);
end
for j=i+1:2
second_img = imread(sprintf('%g.jpg',j));
second_size = size(second_img);
size_temp = size(second_size);
max_size = max(size_temp);
if max_size == 3
second_img = rgb2gray(second_img);
second_size = size(second_img);
end
if i == j
continue;end
if first_size ~= second_size
continue;end
if first_size == second_size
correlation_fs = corr2(first_img,second_img);
if correlation_fs == 1
fprintf('%g is the same as %g\n',first_img,second_img);
end
end
end
end
now, the problem show up when the first image compared to the 3rd dummy image which is exactly the same as the first image.
219 is the same as 219
220 is the same as 220
221 is the same as 221
221 is the same as 222
224 is the same as 223
222 is the same as 221
221 is the same as 222
223 is the same as 224
218 is the same as 236
242 is the same as 232
217 is the same as 219
226 is the same as 228
220 is the same as 229
241 is the same as 251
254 is the same as 253
250 is the same as 247
253 is the same as 253
252 is the same as 248
237 is the same as 224
217 is the same as 218
225 is the same as 219
219 is the same as 223
219 is the same as 214
222 is the same as 237
I don't know why this is showing up, it should print that image 1 is the same as image 3, at least is what i want it to.

You are printing out the entire image matrices instead of the image number. Try:
fprintf('%g is the same as %g\n',i,j)
Think about what first_img is, it's a matrix of pixel intensities. So you're printing out all the pixel values.

fprintf('%g is the same as %g\n',first_img,second_img);
Here you are passing two images as arguments. You should have passed the image numbers instead.
fprintf('%g is the same as %g\n', i, j);

Related

Selecting the maximum matched pairs

I have two groups with different IDs, I got the possible matches by running a code that looked into cases that achieved the criteria, however, it returned for example for one ID from Group A, I have more than one match from Group B. I would like to get rid of the repetition and choose the matched pair randomly that achieved the maximum number of matched pairs at the end. Any Idea of how to solve this?
Here is my code:
SH = readtable('contol_parameters.xlsx','Sheet','m');
%% check if crieria met
numElementsX = length(rmmissing(SH.Ages1));
numElementsY = length(rmmissing(SH.Ages2));
U1 = [];
U2= [];
for r=1:numElementsX
for s=1:numElementsY
if (abs(rmmissing(SH.Ages1(r))-rmmissing(SH.Ages2(s)))<=10) && (abs(rmmissing(SH.vol_1(r))-rmmissing(SH.vol_2(s)))<=10)
U1(end+1)= SH.ID1(r);
U2(end+1)= SH.ID2(s);
end
end
end
%generated list
U_TS=[U1', U2'];
%results
Group A Group B
216 217
216 221
216 222
216 234
216 256
216 262
216 266
216 330
216 390
225 217
225 222
225 234
225 239
225 256
225 257
225 260
225 263
225 266
225 277
225 302
225 324
225 330
225 333
225 341
225 359
225 381
225 386
225 390
225 423
225 435
225 436
225 442
225 466
225 470
225 478
227 257
227 260
227 263
227 277
227 302
If I understand your objective I would try the following:
uA = unique(A);
uB = unique(B);
iCnt = zeros(length(uA),length(uB);
for ii = 1:length(uA)
for jj = 1:length(uB)
iCnt(ii,jj) = sum((A==uA(ii) & B==uB(jj));
end
end
[~,ind] = sort(sum(iCnt),'ascend');
uB = uB(ind);
iCnt = iCnt(:,ind);
%you now have a matrix (iCnt) where the least common members of groupB will be in the leftmost columns of iCnt and for each row (which represents the unique members of GroupA in vector uA) you can find the first non-zero column of iCnt to pick the least common member of GroupB. If that member of B has already been selected previously, you could go to the next non-zero column for another candidate

function returning vector in matlab

I have a function returning a vector in MatLab, the problem is that function should return a unsigned integer value, I've debugged my code and I realize that the variable galois_value turns into a vector when I do a bitand and a bitxor operation. I've tried to do a typecast to turn the vector into a unsigned value but doesn't works. I've tried to force a cast, but doesn't works too. Below the function:
function galois_value = galois_mul2( value )
hex = uint8(hex2dec('1B'));
temp = typecast(value, 'int8');
temp = bitshift(temp,-7);
temp = bitand(typecast(temp,'uint8'),hex);
galois_value = bitxor(bitshift(value,1),uint16(temp));
end
The correct output of this function should be (this output comes from a C code that is working) :
96
210
97
224
119
194
192
156
196
195
102
10
10
117
235
213
49
57
235
79
172
5
23
62
111
188
223
128
113
133
128
102
30
238
226
31
The output I get with the MatLab function:
96 96
210 210
353 378
224 224
375 364
194 194
192 192
156 156
196 196
451 472
102 102
10 10
10 10
373 366
491 496
469 462
305 298
313 290
491 496
335 340
172 172
261 286
279 268
62 62
367 372
188 188
479 452
128 128
369 362
389 414
128 128
102 102
30 30
238 238
226 226
287 260
The code to display and debug the function:
%Key
key = {'00','01','02','03','04','05','06','07','08','09','0a','0b','0c','0d','0e','0f'};
for n = 1 : 16
keyU(n)=uint16(hex2dec(key(n)));
end
%State
state = {'00','11','22','33','44','55','66','77','88','99','aa','bb','cc','dd','ee','ff'};
for n = 1 : 16
stateU(n)=uint16(hex2dec(state(n)));
end
%Sbox
sbox = {'63','7c','77','7b','f2','6b','6f','c5','30','01','67','2b','fe','d7','ab','76','ca','82','c9','7d','fa','59','47','f0','ad','d4','a2','af','9c','a4','72','c0','b7','fd','93','26','36','3f','f7','cc','34','a5','e5','f1','71','d8','31','15','04','c7','23','c3','18','96','05','9a','07','12','80','e2','eb','27','b2','75','09','83','2c','1a','1b','6e','5a','a0','52','3b','d6','b3','29','e3','2f','84','53','d1','00','ed','20','fc','b1','5b','6a','cb','be','39','4a','4c','58','cf','d0','ef','aa','fb','43','4d','33','85','45','f9','02','7f','50','3c','9f','a8','51','a3','40','8f','92','9d','38','f5','bc','b6','da','21','10','ff','f3','d2','cd','0c','13','ec','5f','97','44','17','c4','a7','7e','3d','64','5d','19','73','60','81','4f','dc','22','2a','90','88','46','ee','b8','14','de','5e','0b','db','e0','32','3a','0a','49','06','24','5c','c2','d3','ac','62','91','95','e4','79','e7','c8','37','6d','8d','d5','4e','a9','6c','56','f4','ea','65','7a','ae','08','ba','78','25','2e','1c','a6','b4','c6','e8','dd','74','1f','4b','bd','8b','8a','70','3e','b5','66','48','03','f6','0e','61','35','57','b9','86','c1','1d','9e','e1','f8','98','11','69','d9','8e','94','9b','1e','87','e9','ce','55','28','df','8c','a1','89','0d','bf','e6','42','68','41','99','2d','0f','b0','54','bb','16'};
for n = 1 : 256
sboxU(n)=uint16(hex2dec(sbox(n)));
end
%Rcon
rcon = {'01','02','04','08','10','20','40','80','1b','36'};
for n = 1 : 10
rconU(n)=uint16(hex2dec(rcon(n)));
end
%Main AES Data Loop
for round = 1 : 10
%Add key + sbox
for i = 1 : 16
stateU(i)= sboxU(bitxor(stateU(i),keyU(i))+1);
end
%Shift Rows
buf1 = stateU(2);
stateU(2) = stateU(6);
stateU(6) = stateU(10);
stateU(10) = stateU(14);
stateU(14) = buf1;
buf1 = stateU(3);
buf2 = stateU(7);
stateU(3) = stateU(11);
stateU(7) = stateU(15);
stateU(11) = buf1;
stateU(15) = buf2;
buf1 = stateU(16);
stateU(16) = stateU(12);
stateU(12) = stateU(8);
stateU(8) = stateU(4);
stateU(4) = buf1;
%Process mixcolumn for all rounds but the last one
if round < 10
for j = 0 : 3
%Compute the current index
buf4 = (bitshift(j,2));
%buf1
aux1 = bitxor(stateU(buf4+1),stateU(buf4+2));
aux2 = bitxor(stateU(buf4+3),stateU(buf4+4));
buf1 = bitxor(aux1,aux2);
%buf2
buf2 = stateU(buf4+1);
%buf3
buf3 = bitxor(stateU(buf4+1),stateU(buf4+2));
buf3 = galois_mul2(buf3);
disp(buf3);
end
end
end
The problem is in line 3 of galois_mul2 function
temp = typecast(value, 'int8');
since value has type uint16 output of typecast is two elements.
for e.g. output of typecast(uint16(5), 'int8') is 5 0
If you change all types in lines 3,8,13,18 of main and lines 3,6 of galois_mul2 function to uint8 the problem will be solved.

How can I create a not-equally-spaced sequence of numbers in MATLAB?

I want to create a not-equally-spaced sequence of numbers in MATLAB starting from 24 and ending to 511.The Sequence uses 32 and 33 alternately as the increment. Thus, the sequence would be as below : [24 56 89 121 154 186 219 251 284 316 349 381 414 446 479 511] Notice that :
24+32=56
56+33=89
89+32=121
121+33=154
...
I just wonder how to modify my own codes or to write new codes to have the answer. My own codes are below:
t_3233=0;
for k=24:(32+t_3233):511
t_3233
k
if t_3233==1
t_3233=0;
else if t_3233==0
t_3233=1;
end
end
end
In this particular case you can use:
len = 16;
vector = round(linspace(24,511,len))

How to compute the distance of a set points

I have a problem about computing the distance of points. Let see my definition. I have a finite set points:
S={a_i=(a_i1,a_i2) ∈ Ω, 1<=i<=k }
where Ω is image domain, i is index of pixel.
The distance function d is tuned by parameter sigma that allows adjustment according to the number of points to be fitted:
Let I:Ω->R given by
I= [200 219 226 228 228 240 243 245 245
212 222 229 233 241 247 248 252 252
220 226 234 239 247 250 250 255 253
225 231 244 248 249 248 247 253 250
233 238 251 252 254 249 242 242 235
243 250 255 246 250 244 230 216 200
252 255 250 231 225 211 187 166 153
250 249 234 213 192 164 129 111 114
236 226 195 168 138 119 93 84 91]
Now, I want to compute distance d with a given sigma=3, I want to compute the distance d that follows the above equation. Could you help me implement it by matlab code? Thank you in advance.
If I'm interpreting the equation right, you have k row/column coordinates. For each pair of row/column coordinates you have ai1,ai2, you wish to compute the term inside the brackets of the expression in your post. This results in k matrices, and you'll then have a matrix d such that it's the same size as your image and it computes the product of all of these matrices together.
However, for numerical stability, if you take the logarithmic sum, add up the terms, and then take the exponential of the result, you'll get the same thing and it's actually much quicker (tip of the hat goes to Nikos M. for the tip).
I'd like to note that x seems to be dealing with image coordinates and has nothing to do with the intensities of the image itself. This makes sense given from what I read from the paper. The paper seems to stress that this distance measure looks at spatial locality of pixel locations.
In terms of ease, the quickest way to get something running would be to have a for loop that accumulates all of the results together.
Something like this:
ai1 = [3, 5, 7]; %// Example row coordinates
ai2 = [6, 8, 9]; %// Example column coordinates
%// Image defined by you
I= [200 219 226 228 228 240 243 245 245
212 222 229 233 241 247 248 252 252
220 226 234 239 247 250 250 255 253
225 231 244 248 249 248 247 253 250
233 238 251 252 254 249 242 242 235
243 250 255 246 250 244 230 216 200
252 255 250 231 225 211 187 166 153
250 249 234 213 192 164 129 111 114
236 226 195 168 138 119 93 84 91];
sigma = 3; %// Defined by you
out = zeros(size(I)); %// Define output image
%// Define 2D grid of points
[x1,x2] = ndgrid(1:size(I,1), 1:size(I,2));
for idx = 1 : numel(ai1) %// Or numel(ai2) as it's the same size
%// Compute internal function
p = 1 - exp(-(x1 - ai1(idx)).^2 / (2*sigma^2)).*exp(-(x2 - ai2(idx)).^2 / (2*sigma^2));
%// Accumulate
out = out + log(p);
end
%// Take anti-log
out = exp(out);
Bear in mind that the above notation is with respect to 1-indexing as MATLAB starts indexing things at 1. Traditionally, image indexing starts at 0, so if you want to start at 0, simply offset ai1 and ai2 by 1, and also in the ndgrid call, subtract the values by 1.
So, modify here:
ai1 = [3, 5, 7] - 1; %// Example row coordinates
ai2 = [6, 8, 9] - 1; %// Example column coordinates
... and here:
%// Define 2D grid of points
[x1,x2] = ndgrid(1:size(I,1), 1:size(I,2));
x1 = x1 - 1; x2 = x2 - 1;
I'm assuming that the zero-indexing is what is desired. As such, with the above code, I get this as the output:
out =
Columns 1 through 8
1.6849 1.1763 0.7129 0.3843 0.2042 0.1387 0.1508 0.2215
1.5092 0.9580 0.4959 0.2025 0.0633 0.0242 0.0372 0.0784
1.4192 0.8515 0.4004 0.1353 0.0236 0 0.0089 0.0249
1.4240 0.8534 0.4032 0.1427 0.0348 0.0084 0.0057 0.0056
1.5171 0.9519 0.4857 0.2003 0.0682 0.0208 0.0047 0
1.6802 1.1341 0.6418 0.3054 0.1241 0.0424 0.0110 0.0029
1.8866 1.3832 0.8733 0.4735 0.2227 0.0903 0.0304 0.0073
2.1040 1.6730 1.1773 0.7265 0.3965 0.1940 0.0855 0.0342
2.3020 1.9666 1.5312 1.0730 0.6811 0.4020 0.2315 0.1446
Column 9
0.3566
0.1563
0.0594
0.0180
0.0056
0.0036
0
0.0199
0.1250
As you can see, the row and column coordinates of what we specified in ai1 and ai2 are zero in the distance matrix while the rest of the points reflect the rough distance from each of the anchor points. It honestly looks like a watered down version of the distance transform. The zero coefficients make perfect sense. Remember, we are taking the product of all of the k matrices together for the final output, and what's going to happen is that x1 and x2 will certainly have a ai1 / ai2 pair and so the subtraction in the exponent thus leads to a 1 output, and 1 - 1 = 0, and the product of anything (except infinity) with 0 is 0.... hence the reason why there's a 0 coefficient there!

Error in for loop in matlab

I have an error in the following forloop. I know because the end value of the first for is going to be changed and it is not acceptable for Matlab to change in inside iteration. But would you have any idea how to overcome to it? By the way I used while, but does not help me at all. Data are as follow:
D = [
2.39484592826072e-05 286
4.94140791861196e-05 161
5.07906972800045e-05 163
0.000103133134300751 141
0.000142755898501384 136
0.000143741615840070 152
0.000188072960663613 177
0.000203545320971960 1
0.000269110781516704 296
0.000333161025069404 293
0.000351184122591795 167
0.000393661764751196 299
0.000469154814856272 173
0.000516662289403544 181
0.000537612407901054 156
0.000698464342131732 246
0.000848447859349023 66
0.000875283151707512 75
0.00102377583629824 68
0.00110034589129900 277
0.00110693756077989 129
0.00120680501123819 87
0.00151080017572355 78
0.00159156469379168 248
0.00190852817897233 270
0.00192106167039306 133
0.00224677708557380 258
0.00246430115488258 264
0.00288772180685041 255
0.00299392149856582 81
0.00315341807121748 242
0.00327625233716732 27
0.00362308575885149 124
0.00434568780796603 220
0.00443389247698617 239
0.00470947127244510 60
0.00474015278667278 23
0.00481651908877289 230
0.00487750364266560 53
0.00510342992049100 56
0.00513758569662983 228
0.00515453564704144 121
0.00515656244518627 232
0.00526922882200147 8
0.00547349131456174 50
0.00553337871530176 117
0.00569159206242299 18
0.00620144292620718 13
0.00630382865700000 119
0.00755647842280271 92
0.00983041839684126 40
0.00997057619578698 98
0.0102611966834032 44
0.0103337998140422 100
0.0105132461082006 37
0.0106952804631761 109
0.0107424055503829 208
0.0109630950142485 111
0.0115094667290339 105
0.0119529682389369 107];
ymin= D(:,1);
mean_value = 0.00773867192661190;
criteria = min(ymin);
kk = 1;
diff = 60;
and here is the code that I would have an error for the changing size_D which is expected.
while criteria < mean_value
if isempty(B)
ind_crt = find(min(ymin));
B(kk,:) = D(ind_crt,:);
D(ind_crt,:) = [];
kk = kk + 1;
end
criteria = min(min(D));
size_D = size(D,1);
for ii=1:size_D
if D(ii,1) == criteria
size_B = size(B,1);
for jj = 1:size_B
if abs(D(ii,2) - B(jj,2)) > diff
B(kk,:) = D(ii,:);
D(ii,:)= [];
kk = kk + 1;
end
size_D = size_D -1;
criteria = min(min(D))
end
end
end
end
Update:
Here is the error:
Attempted to access D(59,1); index out of bounds because
size(D)=[58,2].
Error in local_minima (line 50)
if D(ii,1) == criteria
Replace your for loop by a while loop, so that the code in the loop is run only if the condition ii<=size_D is verified:
ii=0;
while ii<=size_D
ii=ii+1;
%loop code
instead of the
for ii=1:size_D
%loop code