کار با correlation در متلب
در این نوشته به کمک correlation از بین یک جمع چهرهی فرد تشخیص داده میشود البته دقت کنید ممکن است کمی خطا داشته باشد یا با تصاویر مختلف به مشکل بخورد ولی تا حد زیادی الگوریتم correlation پیاده سازی شده است.
کار با correlation در متلب

![]()
کد main.m:
clc;
clear all;
close all;
image_ref = imread('img/image_ref.jpg');
filter = imread('img/filter.jpg');
image = image_ref;
filter = filter;
correlation = normxcorr2(filter(:,:), image(:,:));
figure, imshow(correlation);
title('Correlation image');
[maxCorrValue, maxIndex] = max(abs(correlation(:)));
[yPeak, xPeak] = ind2sub(size(correlation), maxIndex(1));
corr_offset = [(xPeak - size(filter, 2)) (yPeak - size(filter, 2))];
if(corr_offset(1) < 0)
corr_offset(1) = corr_offset(1) * (-1);
end
if(corr_offset(2) < 0)
corr_offset(2) = corr_offset(2) * (-1);
end
axis on;
hold on;
figure, imshow(image);
title('find area');
boxRect = [corr_offset(1) corr_offset(2) 200, 200];
rectangle('position', boxRect, 'edgecolor', 'r', 'linewidth', 2);
کد main2.m:
clc;
close all;
clear all;
image_ref = imread('img/image_ref.jpg');
filter = imread('img/filter_ssim.jpg');
image = image_ref;
filter = filter;
image_ref_size = size(image_ref);
filter_size = size(filter);
temp_result = 0;
corr2val = 0;
ssim_result = zeros(image_ref_size(1), image_ref_size(2), 'int8');
K = [0.1 0.3];
window = fspecial('gaussian', 10, 2.5);
L = 255;
for m = round(filter_size(1) / 2) : image_ref_size(1)
if(m + filter_size(1) > image_ref_size(1))
break;
end
for n = round(filter_size(2) / 2) : image_ref_size(2)
image_temp = zeros(filter_size(1), filter_size(2));
if(n + filter_size(2) > image_ref_size(2))
break;
end
for i = m : m + filter_size(1)
for j = n : n + filter_size(2)
image_temp(i, j) = image_ref(i, j);
end
end
res = ssim(image_temp, filter, K, window, L);
if(res < 0)
res = res * (-1);
end
temp_result = round(res * 255);
ssim_result(m, n) = int8(temp_result);
end
end
figure, imshow(ssim_result);
title('find area with ssim');
کد ssim.m:
function res = ssim(image1_filename, image2_filename, K, window, L)
image1 = image1_filename;
image2 = image2_filename;
ssim_map = -Inf;
if (nargin < 2 || nargin > 5)
res = -Inf;
ssim_map = -Inf;
return;
end
if (size(image1) ~= size(image2))
res = -Inf;
ssim_map = -Inf;
return;
end
[M N] = size(image1);
if (nargin == 2)
if ((M < 11) || (N < 11))
res = -Inf;
ssim_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5);
K(1) = 0.01;
K(2) = 0.03;
L = 255;
end
if (nargin == 3)
if ((M < 11) || (N < 11))
res = -Inf;
ssim_map = -Inf;
return
end
window = fspecial('gaussian', 11, 1.5);
L = 255;
if (length(K) == 2)
if (K(1) < 0 || K(2) < 0)
res = -Inf;
ssim_map = -Inf;
return;
end
else
res = -Inf;
ssim_map = -Inf;
return;
end
end
if (nargin == 4)
[H W] = size(window);
if ((H*W) < 4 || (H > M) || (W > N))
res = -Inf;
ssim_map = -Inf;
return
end
L = 255;
if (length(K) == 2)
if (K(1) < 0 || K(2) < 0)
res = -Inf;
ssim_map = -Inf;
return;
end
else
res = -Inf;
ssim_map = -Inf;
return;
end
end
if (nargin == 5)
[H W] = size(window);
if ((H*W) < 4 || (H > M) || (W > N))
res = -Inf;
ssim_map = -Inf;
return
end
if (length(K) == 2)
if (K(1) < 0 || K(2) < 0)
res = -Inf;
ssim_map = -Inf;
return;
end
else
res = -Inf;
ssim_map = -Inf;
return;
end
end
image1 = double(image1);
image2 = double(image2);
f = max(1,round(min(M,N)/256));
if(f>1)
lpf = ones(f,f);
lpf = lpf/sum(lpf(:));
image1 = imfilter(image1,lpf,'symmetric','same');
image2 = imfilter(image2,lpf,'symmetric','same');
image1 = image1(1:f:end,1:f:end);
image2 = image2(1:f:end,1:f:end);
end
C1 = (K(1)*L)^2;
C2 = (K(2)*L)^2;
window = window/sum(sum(window));
mu1 = filter2(window, image1, 'valid');
mu2 = filter2(window, image2, 'valid');
mu1_sq = mu1.*mu1;
mu2_sq = mu2.*mu2;
mu1_mu2 = mu1.*mu2;
sigma1_sq = filter2(window, image1.*image1, 'valid') - mu1_sq;
sigma2_sq = filter2(window, image2.*image2, 'valid') - mu2_sq;
sigma12 = filter2(window, image1.*image2, 'valid') - mu1_mu2;
if (C1 > 0 && C2 > 0)
ssim_map = ((2*mu1_mu2 + C1).*(2*sigma12 + C2))./((mu1_sq + mu2_sq + C1).*(sigma1_sq + sigma2_sq + C2));
else
numerator1 = 2*mu1_mu2 + C1;
numerator2 = 2*sigma12 + C2;
denominator1 = mu1_sq + mu2_sq + C1;
denominator2 = sigma1_sq + sigma2_sq + C2;
ssim_map = ones(size(mu1));
index = (denominator1.*denominator2 > 0);
ssim_map(index) = (numerator1(index).*numerator2(index))./(denominator1(index).*denominator2(index));
index = (denominator1 ~= 0) & (denominator2 == 0);
ssim_map(index) = numerator1(index)./denominator1(index);
end
res = mean2(ssim_map);
return
روشهای انجام Correlation
- بخش اول در فایل m انجام میشود.
- بدست آوردن correlation با تابع corr2 متلب انجام شده است.
- خروجی به صورت یک تصویر سیاهی و سفیدی است که مکانهایی که شباهت دارند روشنتر هستند.
- خروجی دوم در عکس اصلی است که مکانی که شباهت بیشتری داشته را انتخاب کرده است.
- بخش دوم در فایل m است.
- تابع مورد استفاده برای ssim که در این تمرین استفاده شده است در تمرینهای قبلی انجام شده است.
- در بخش دوم تمرین یک حلقهی تو در تو با در نظر گرفتن padding داریم که هر بار یک قسمت از عکس اصلی به اندازهی فیلتر را میبرد و مقدار ssim آن را محاسبه میکنیم.
- نتایج ssim را در یک ماتریس خروجی ذخیره میکنیم و در نهایت آن را نمایش میدهیم.
خروجی


برای مطالعهی محتوای بیشتر در ارتباط با متلب روی این لینک کلیک کنید. نظرات خود را برای ما بنویسید.
برای امتیاز به این نوشته کلیک کنید!
[کل: 1 میانگین: 5]



















انتخاب اندازهی پنجره گوسی در SSIM چه اثری روی نقاط روشن خروجی میذاره؟
انتخاب اندازهی پنجره گوسی در SSIM بر میزان نرمالسازی و در نتیجه بر حساسیت الگوریتم به تغییرات محلی در تصویر تأثیر میگذارد. پنجره بزرگتر باعث نرمالسازی بیشتر و کاهش حساسیت به جزئیات ریز میشود.
اگر فیلتر نسبت به تصویر چرخیده یا مقیاسش تغییر کرده باشه، این روش هنوز جواب میده؟
روش correlation به تغییرات چرخش و مقیاس تصویر فیلتر حساس است و در این حالت ممکن است نتایج دقیقی ارائه ندهد. برای این موارد نیاز به الگوریتمهای پیچیدهتری است.
قبل از همبستگی، تصویرها رو نرمالسازی یا همسانسازی روشنایی کردید؟
در این کد، مستقیماً از تصاویر ورودی استفاده شده و نرمالسازی روشنایی قبل از محاسبه همبستگی انجام نشده است.
چرا از normxcorr2 استفاده کردید و نه corr2 برای تطبیق الگو؟
تابع `normxcorr2` برای تطبیق الگو در دو بعد و با در نظر گرفتن نرمالسازی مقیاس و روشنایی مناسبتر است، به همین دلیل در این مثال از آن استفاده شد.
تشکر بابت این مقاله
موفق باشید.
در حلقهی استخراج پنجره برای SSIM، چرا از ایندکسهای مطلق تصویر استفاده شده و نه مختصات نسبی داخل پنجره؟
با سلام، در این پیادهسازی، از ایندکسهای مطلق برای سادگی و دسترسی مستقیم به مقادیر پیکسلها استفاده شده است. البته، استفاده از مختصات نسبی نیز امکانپذیر است و میتواند در برخی موارد خوانایی کد را افزایش دهد.
چرا در کد ssim بررسی برابری اندازهها بهصورت برداری انجام شده و آیا برای تصاویر رنگی نیاز به پردازش کانالبهکانال نیست؟
سلام. در کد ssim، بررسی برابری اندازه ها برای اطمینان از سازگاری ابعاد تصاویر انجام شده است. بله، برای تصاویر رنگی، معمولاً پردازش کانال به کانال برای محاسبه ssim لازم است.
اگر اندازهی فیلتر نسبت به تصویر مرجع خیلی بزرگ باشد، normxcorr2 چه رفتاری نشان میدهد و راهحل پیشنهادی چیست؟
سلام، اگر فیلتر خیلی بزرگ باشد، normxcorr2 ممکن است نتایج نامناسبی تولید کند و ناحیهی مورد نظر را به درستی پیدا نکند. در این حالت، بهتر است اندازهی فیلتر را متناسب با اندازهی تصویر مرجع تنظیم کنید یا از روشهای دیگری مانند کاهش اندازهی تصویر استفاده کنید.
برای آستانهگذاری روی نقشهی همبستگی، چه معیاری برای تشخیص ناحیهی معتبر در نظر گرفته شده؟
با سلام. در این کد، برای تعیین ناحیهی معتبر، از بیشترین مقدار همبستگی (maxCorrValue) استفاده شده و موقعیت آن در تصویر همبستگی مشخص میشود.
قبل از محاسبهی normxcorr2 تصاویر به مقیاس خاکستری و double نرمال شدهاند یا با همان مقادیر uint8 استفاده شده؟
با سلام. در این کد، تصاویر ورودی به صورت پیشفرض با مقادیر uint8 خوانده میشوند و normxcorr2 مستقیماً روی آنها اعمال میشود.