مقدمه
برای ذخیرهسازی تصویر به دنبال روشی هستیم تا به کمک آن بتوانیم حجم اطلاعات را تا جایی که ممکن است کاهش دهیم. اساس بسیاری از روشهای فشردهسازی، کنار گذاردن بخشهایی از اطلاعات و دادهها است. ضریب یا نسبت فشردهسازی، عددی است که میزان کنار گذاشتن اطلاعات را نشان میدهد.
فشرده سازی تصاویر، ذخیرهکردن و انتقال آنها را آسانتر میکند و میتواند سبب کاهش پهنای باند و فرکانس مورد نیاز برای ارسال تصاویر شود. یکی از روشهای فشرده سازی تصویر، تکنیک چندی سازی برداری است.برای چندی سازی برداری ابتدا باید تصویر را قطعه بندی یا به عبارتی به تعدادی بلاک تقسیم کرد.با استفاده از کد ذیل، مفهوم تقسیم یک تصویر به تعدادی بلاک شرح داده می شود.
کد داده شده (انتهای سند)سگمنت –تقسیم بندی تصاویر را به دو روش نشان می دهد:
1- سگمنت بندی تصویر با استفاده از تابع mat2cell()
2- سگمنت بندی تصویر با استفاده از شاخص گذاری کردن – index
روش 1 : استفاده از تابع ()mat2cell
نشان دادن سگمنت کردن تصویر،از تصویر نمونه 'peppers.png' بصورت رنگی و یا سیاه – سفید کمک می گیریم.
قسمت اول کد: خواندن تصویر
29. set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
30. drawnow
با استفاده از دستور فوق (normalized:units) موقعیت figure یا همان خروجی، را می توان مستقل از تغییرات صفحه نمایش یعنی با توجه به اندازه صفحه نمایش،تنظیم نمود.اگر قرار است کد نوشته شده در سیستم های رایانه ای مختلف مورد استفاده قرار گیرد،استفاده از دستور نامبرده برای تنظیم موقعیت figure مناسب می باشد.
31. % Get the dimensions of the image. Number Of ColorBands should be = 3.
تعداد ابعاد تصویر را 3 نظر می گیریم.(استفاده از تصویر رنگی)
32. [rows columns numberOfColorBands] = size(rgbImage)
بدست آوردن اندازه و بعد تصویر با دستور size(file name)
:row تعداد پیکسلهای تصویر در راستای افق- سطر
: Columns تعداد پیکسلهای تصویر در راستای ارتفاع- ستون
numberOfColorBands: تعداد ابعاد تصویر - 3رنگ اصلی
Rows= 384 , columns= 512, numberOfColorBands =3
قسمت دوم کد : مشخص کردن اندازه هر بلاک از تصویر: تعداد پیکسلهای سطر و ستون در هر بلاک.
با توجه به تعداد پیکسلهای تصویر (در سطر و ستون) و تعداد پیکسلهای هر بلاک در سطر و ستون ،از دستور floor برای گرد کردن کمک میگیریم
دستور ones:
این دستور ماتریسی ایجاد می کند که تمامی عناصر آن دارای مقدار عددی 1 می باشند.
به مثال زیر توجه کنید :ماتریسی می سازیم که دارای 2 ردیف و 3 ستون باشد و تمامی عناصر آن دارای مقدار عددی 1 باشند
A=ones(2,3);
RUN:
ones(1, wholeBlockRows);
ماتریس شامل یک ردیف که ستونهای آن wholeBlockRows می باشد.
rem(rows, blockSizeR)];
محاسبه باقیماتده حاصل از تقسیم
با کدهای خطوط 37 تا 41،مشخص میکنیم که در خروجی، در هر ردیف و ستون، چند قطعه از تصویر با توجه اندازهی بلاکی که داده ایم نمایش داده شود.
size('peppers.png'): Rows= 384, columns=512
blockSizeR = 150; % Rows in block
blockSizeC = 100; % Columns in block.
خروجی کار تا این مرحله از کار با توجه به مقادیر داده شده :
Rows= 384 , columns =512
numberOfColorBands=3;
blockSizeR = 100 ; blockSizeC = 150
wholeBlockRows=3 ; blockVectorR=100 84 100 100
wholeBlockCols= 3 ;blockVectorC=150 150 150 62
قسمت سوم :نحوه نمایش بلاک های ایجاد شده از تقسیم بندی تصویر با استفاده از دستور ()mat2cell
در مرحله قبلی مشخص شد که چه تعداد از پیکسلهای تشکیل دهنده تصویر در یک بلاک قرار میگیرند در واقع اندازه هر بلاک در مرحله قبلی مشخص شد که چه تعداد از پیکسلهای تشکیل دهنده تصویر در یک بلاک قرار میگیرند در واقع اندازه هر بلاک تعیین شد. بعد از مشخص کردن محدوده هر بلاک از تصویر به مرحله نمایش آنها می رسیم.
برای اینکار ، می توان از حلقه های for و یک اندیس جهت شمارش بلاک ها ، استفاده نمود. (خطوط 84 به بعد).
numberOfColorBands > 1 : نشاندهنده یک تصویر رنگی است
mat2cell یک ماتریس بزرگ را به آرایه هایی کوچکتر تبدیل می کند. همانطور که میدانیم یک تصویر ، یک ماتریس محسوب می شود که با mat2cell تصویر را به مجموعه ای از بردارها تبدیل می کنیم.
if numberOfColorBands > 1
% It's a color image.
ca = mat2cell(rgbImage, blockVectorR, blockVectorC, numberOfColorBands)
else
ca = mat2cell(rgbImage, blockVectorR, blockVectorC)
end
مفهوم تابع mat2cell با یک مثال ساده : تبدیل آرایه X به 6 آرایه کوچکتر
c = mat2cell(x, [10, 20, 30], [25, 25])
divides a 60-by-50 array into six arrays contained in a cell array.
For the kth dimension, sum(dimkDist) == size(A,k).
تابع size برای استخراج اندازه ماتریس کاربرد دارد و سایز کامل ماتریس و یا سایز ماتریس در راستای بعد مشخصی را بر می گرداند.
تبدیل تصویر مورد استفاده به مجموعه ای از آرایه ها
=ca
[100x150x3 uint8] [100x150x3 uint8] [100x150x3 uint8] [100x62x3 uint8]
[100x150x3 uint8] [100x150x3 uint8] [100x150x3 uint8] [100x62x3 uint8]
[100x150x3 uint8] [100x150x3 uint8] [100x150x3 uint8] [100x62x3 uint8]
[100x150x3 uint8] [100x150x3 uint8] [100x150x3 uint8] [100x62x3 uint8]
plotIndex = 1;
مقدار دهی اولیه اندیس شمارشی بلاک ها
numPlotsR = size(ca, 1)
نمایش تعداد سطر ماتریس ca
numPlotsC = size(ca, 2)
نمایش تعداد ستون ماتریس ca
و در پایان ،کدهای خطوط 90 به بعد ،نمایش بلاک های تصویر را انجام می دهند.
'baseFileName = 'peppers.png
Rows= 384 ; columns= 512 ; numberOfColorBands =3;
blockSizeR = 100 ; blockSizeC = 150
wholeBlockRows= 3 ; blockVectorR = 100 100 100 84
wholeBlockCols = 3; blockVectorC= 150 150 150 62
baseFileName =’ Lena_Gray.jpg’;
Rows= 512 ; columns= 512 ; numberOfColorBands =1 ; % rgbImage = rgb2gray(rgbImage);
blockSizeR = 150 ; blockSizeC = 200;
wholeBlockRows = 3 ; blockVectorR = 150 150 150 62
wholeBlockCols = 2 ; blockVectorC = 200 200 112
% Demo to divide an image up into blocks (non-overlapping tiles).
% The first way to divide an image up into blocks is by using mat2cell().
% In this demo, I demonstrate that with a color image.
% Another way to split the image up into blocks is to use indexing.
% In this demo, I demonstrate that method with a grayscale image.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
workspace; % Make sure the workspace panel is showing.
fontSize = 20;
% Read in a standard MATLAB color demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'peppers.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
% Read the image from disk.
rgbImage = imread(fullFileName);
% Test code if you want to try it with a gray scale image.
% Uncomment line below if you want to see how it works with a gray scale image.
% rgbImage = rgb2gray(rgbImage);
% Display image full screen.
imshow(rgbImage);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
drawnow;
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage)
%==========================================================================
% The first way to divide an image up into blocks is by using mat2cell().
blockSizeR = 100; % Rows in block.
blockSizeC = 150; % Columns in block.
% Figure out the size of each block in rows.
% Most will be blockSizeR but there may be a remainder amount of less than that.
wholeBlockRows = floor(rows / blockSizeR);
blockVectorR = [blockSizeR * ones(1, wholeBlockRows), rem(rows, blockSizeR)];
% Figure out the size of each block in columns.
wholeBlockCols = floor(columns / blockSizeC);
blockVectorC = [blockSizeC * ones(1, wholeBlockCols), rem(columns, blockSizeC)];
% Create the cell array, ca.
% Each cell (except for the remainder cells at the end of the image)
% in the array contains a blockSizeR by blockSizeC by 3 color array.
% This line is where the image is actually divided up into blocks.
if numberOfColorBands > 1
% It's a color image.
ca = mat2cell(rgbImage, blockVectorR, blockVectorC, numberOfColorBands);
else
ca = mat2cell(rgbImage, blockVectorR, blockVectorC);
end
% Now display all the blocks.
plotIndex = 1;
numPlotsR = size(ca, 1);
numPlotsC = size(ca, 2);
for r = 1 : numPlotsR
for c = 1 : numPlotsC
fprintf('plotindex = %d, c=%d, r=%d\n', plotIndex, c, r);
% Specify the location for display of the image.
subplot(numPlotsR, numPlotsC, plotIndex);
% Extract the numerical array out of the cell
% just for tutorial purposes.
rgbBlock = ca{r,c};
imshow(rgbBlock); % Could call imshow(ca{r,c}) if you wanted to.
[rowsB columnsB numberOfColorBandsB] = size(rgbBlock);
% Make the caption the block number.
caption = sprintf('Block #%d of %d\n%d rows by %d columns', ...
plotIndex, numPlotsR*numPlotsC, rowsB, columnsB);
title(caption);
drawnow;
% Increment the subplot to the next location.
plotIndex = plotIndex + 1;
end
end
% Display the original image in the upper left.
subplot(4, 6, 1);
imshow(rgbImage);
title('Original Image');
سلام
سوال
۱-اندازه بلاک ها را بر اساس چه معیاری انتخاب میکنید؟
۲-آیا خوشه بندی در سطح بلاک میباشد در این صورت بر اساس کدام خصوصیت تصویر خوشه بندی میکنید(بر اساس محتوای پیکسل که همان کد رنگ می باشد و یا محل قرار گیری پیکسل)؟
۳- اگر خوشه بندی بگدرون بلاک باشد چند خوشه درون هر بلاک قرار میگیرد(centroid)؟
با تشکر
با سلام و تبریک سال نو
امیدوارم با مطالعه پست ذیل به جواب برسید
"مروری بر تولیدکدبوک به روش VQ"
http://vq-haghjoo.blogsky.com/1396/12/16/post-13/