Современные технологии обработки изображений 25

Уменьшение количества градаций цветных изображений

Довольно часто возникает задача уменьшения количества градаций, которые используются при визуализации цветных изображений. Иными словами, задача заключается в модификации палитры. Ранее нами уже были рассмотрены некоторые подходы к решению этой задачи. В этом материале рассмотрим еще несколько методов уменьшения количества цветов, которые используются при визуализации цветных изображений.

Метод 1. Суть этого метода состоит в том, что диапазон каждой цветовой составляющей делится на нужное количество градаций. Однако разделение выполняется таким образом, чтобы на изображении было также равное количество пикселей, которые принимают значения из всех поддиапазонов.

Продемонстрируем программную реализацию данного метода.

Сначала считаем исходное изображение из графического файла в рабочее пространство Matlab.

L=imread('im.bmp');
L=double(L);

Далее визуализируем его.

figure, imshow(L./255);

Определим размеры исходного изображения и количество градаций цветовых составляющих для нового изображения.

[N M k]=size(L);

%Количество цветов

rgb=2;

Теперь будем обрабатывать каждую цветовую составляющую отдельно.

Рассмотрим преобразование красной цветовой составляющей более подробно.

Сначала необходимо выделить первый цветовой шар изображения.

LR=L(:,:,1);

Далее необходимо построить гистограмму распределения значений первого цветового шара изображения.

HR=hist(LR(:),256);

Теперь необходимо реализовать разделение исходного диапазона на поддиапазоны. Как уже отмечалось выше, главное условие при проведении такого разделения заключается в том, что на исходном изображении должно быть одинаковое количество пикселей, которые принимают значения из каждого поддиапазона. Это позволит максимально сохранить детальность на преобразованном изображении.

for KolColor=1:rgb;
Htemp=0;
i=1;
while i<256;
    Htemp=Htemp+HR(i);
    if Htemp>=( KolColor /rgb-1/(2*rgb))*N*M;
        PorogR(KolColor)=i;
        i=256;
    end;
    i=i+1;
end;
end;

Аналогичные преобразования реализуются для зеленой и синей цветовой составляющих.

%========Зеленая цветовая составляющая ============

LG=L(:,:,2);
HG=hist(LG(:),256);
for KolColor =1:rgb;
Htemp=0;
i=1;
while i<256;
    Htemp=Htemp+HG(i);
    if Htemp>=( KolColor /rgb-1/(2*rgb))*N*M;
        PorogG(KolColor)=i;
        i=256;
    end;
    i=i+1;
end;
end;

%===========Синяя цветовая составляющая==========

LB=L(:,:,3);
HB=hist(LB(:),256);
for KolColor =1:rgb;
Htemp=0;
i=1;
while i<256;
    Htemp=Htemp+HB(i);
    if Htemp>=( KolColor /rgb-1/(2*rgb))*N*M;
        PorogB(KolColor)=i;
        i=256;
    end;
    i=i+1;
end;
end;

После модификации градаций, необходимо соответственно модифицировать и значения пикселей изображения. Причем это необходимо сделать таким образом, чтобы новое модифицированное значение пикселя было расположено максимально близко к предыдущему немодифицированному значению.

for i=1:N;
    disp(i);
    for j=1:M;
        [y NomerR]=min(abs(PorogR-L(i,j,1)));
        [y NomerG]=min(abs(PorogG-L(i,j,2)));
        [y NomerB]=min(abs(PorogB-L(i,j,3)));
        
        L1(i,j,1)=PorogR(NomerR);
        L1(i,j,2)=PorogG(NomerG);
        L1(i,j,3)=PorogB(NomerB);
    end;    
end;

Представим результат преобразований.

figure, imshow(L1./255);

Отметим, что этот результат получен при двух градациях каждой цветовой составляющей.

Если диапазоны каждой цветовой составляющей разделить на семь поддиапазонов, то получим следующий результат.

Если же диапазоны цветовых составляющих разделить на 15 поддиапазонов, то получим такой результат.

Из проведенных экспериментов можно сделать вывод, что результат преобразования во многом зависит от количества градаций – чем их больше, тем результат более визуально приемлемый.

 

Метод 2. В предыдущем методе анализ и последующее преобразование проводилось над всем изображением сразу, т.е. метод был глобальным. В этом методе рассмотрим применение этой же методики только к локальным окрестностям. В большинстве случаев такой подход обеспечивает более детальную обработку изображений.

Сначала считаем исходное изображение и визуализируем его.

L=imread('im.bmp');
L=double(L(:,:,:));
figure, imshow(L./255);

Далее необходимо определить размеры изображения, количество цветовых составляющих исходного изображения и количество градаций цветовых составляющих, которые будут на модифицированном изображении.

[N M k]=size(L);

%Количество цветов

rgb=2; 

Поскольку этот метод предусматривает обработку с использованием локальных апертур, то для корректной программной реализации необходимо провести расширение границ исходного изображения. Проведем расширение границ для каждой цветовой составляющей отдельно.

%Расширение исходного массива R-цветовой составляющей

LR=(L(:,:,1));
m=7;n=m;n1=fix(n/2);m1=fix(m/2);
a=LR(1,1);b=LR(1,M);c=LR(N,1);d=LR(N,M);
for i=1:n1;  for j=1:m1;
    LR1(i,j)=a;    LR3(i,j)=b;    LR6(i,j)=c;    LR8(i,j)=d;
end;end;
   LR2=LR(1,1:M);   LR02=LR2;
    for i=1:n1-1;      LR2=[LR2;LR02];    end;
    LR7=LR(N,1:M);    LR07=LR7;
        for i=1:n1-1;          LR7=[LR7;LR07];        end;
     LR4=LR(1:N,1);     LR4=LR4';     LR04=LR4;
          for i=1:m1-1;            LR4=[LR4;LR04];          end;
       LR4=LR4';  LR5=LR(1:N,M);  LR5=LR5';   LR05=LR5;
    for i=1:m1-1;      LR5=[LR5;LR05];    end;
     LR5=LR5';  LR1=[LR1;LR4];  LR1=[LR1;LR6];  LR1=LR1';  LR2=[LR2;LR];  LR2=[LR2;LR7];
  LR2=LR2';  LR3=[LR3;LR5];  LR3=[LR3;LR8];  LR3=LR3';  LR1=[LR1;LR2];  LR1=[LR1;LR3];
  LRR=LR1';
  clear LR1;  clear LR2;  clear LR3;  clear LR4;  
    clear LR5;  clear LR6;  clear LR7;  clear LR8; clear LR;

%Расширение исходного массива G-цветовой составляющей

LG=(L(:,:,2));
a=LG(1,1);b=LG(1,M);c=LG(N,1);d=LG(N,M);
for i=1:n1;  for j=1:m1;
    LG1(i,j)=a;    LG3(i,j)=b;    LG6(i,j)=c;    LG8(i,j)=d;
end;end;
   LG2=LG(1,1:M);   LG02=LG2;
    for i=1:n1-1;      LG2=[LG2;LG02];    end;
    LG7=LG(N,1:M);    LG07=LG7;
        for i=1:n1-1;          LG7=[LG7;LG07];        end;
     LG4=LG(1:N,1);     LG4=LG4';     LG04=LG4;
          for i=1:m1-1;            LG4=[LG4;LG04];          end;
       LG4=LG4';  LG5=LG(1:N,M);  LG5=LG5';   LG05=LG5;
    for i=1:m1-1;      LG5=[LG5;LG05];    end;
     LG5=LG5';  LG1=[LG1;LG4];  LG1=[LG1;LG6];  LG1=LG1';  LG2=[LG2;LG];  LG2=[LG2;LG7];
  LG2=LG2';  LG3=[LG3;LG5];  LG3=[LG3;LG8];  LG3=LG3';  LG1=[LG1;LG2];  LG1=[LG1;LG3];
  LRG=LG1';
  clear LG1;  clear LG2;  clear LG3;  clear LG4;  
    clear LG5;  clear LG6;  clear LG7;  clear LG8; clear LG;

%Расширение исходного массива B-цветовой составляющей

LB=(L(:,:,3));
a=LB(1,1);b=LB(1,M);c=LB(N,1);d=LB(N,M);
for i=1:n1;  for j=1:m1;
    LB1(i,j)=a;    LB3(i,j)=b;    LB6(i,j)=c;    LB8(i,j)=d;
end;end;
   LB2=LB(1,1:M);   LB02=LB2;
    for i=1:n1-1;      LB2=[LB2;LB02];    end;
    LB7=LB(N,1:M);    LB07=LB7;
        for i=1:n1-1;          LB7=[LB7;LB07];        end;
     LB4=LB(1:N,1);     LB4=LB4';     LB04=LB4;
          for i=1:m1-1;            LB4=[LB4;LB04];          end;
       LB4=LB4';  LB5=LB(1:N,M);  LB5=LB5';   LB05=LB5;
    for i=1:m1-1;      LB5=[LB5;LB05];    end;
     LB5=LB5';  LB1=[LB1;LB4];  LB1=[LB1;LB6];  LB1=LB1';  LB2=[LB2;LB];  LB2=[LB2;LB7];
  LB2=LB2';  LB3=[LB3;LB5];  LB3=[LB3;LB8];  LB3=LB3';  LB1=[LB1;LB2];  LB1=[LB1;LB3];
  LRB=LB1';
  clear LB1;  clear LB2;  clear LB3;  clear LB4;  
    clear LB5;  clear LB6;  clear LB7;  clear LB8; clear LB;
        
    Lr(:,:,1)=LRR;
    Lr(:,:,2)=LRG;
    Lr(:,:,3)=LRB;

Таким образом, нами сформирован массив исходного изображения Lr с расширенными границами.

Далее все операции будут аналогичны, как и в методе 1. Как уже отмечалось, главная особенность такой обработки будет заключаться в том, что она будет выполняться не сразу над всем изображением, а над его локальными окрестностями.

for i=1+n1:N+n1;
    disp(i);
    for j=1+m1:M+m1;
                 if j==1+m1;
                        D=0;
% Формирование локальной окрестности
                        for a=-n1:n1;
                        for b=-m1:m1;                           
                           D(n1+1+a,m1+1+b,1:3)=Lr(i+a,j+b,1:3);
                        end;
                        end;
                 end;
           if j>1+m1;
            for a=-n1:n1;
              D(n1+1+a,m+1,1:3)=Lr(i+a,j+m1,1:3);
            end;
             D=D(1:n,2:m+1,1:3);
          end;            

Далее обработка будет выполняться для каждой цветовой составляющей отдельно.

%Для цветовой R-составляющей изображения
LRmal=D(:,:,1);
HR=0;
HR=hist(LRmal(:),256);
PorihR=ones(1,rgb);
for KilkistKolioriv=1:rgb;
Htemp=0;
t=1;
while t<256;
    Htemp=Htemp+HR(t);
    if Htemp>=(KilkistKolioriv/rgb-1/(2*rgb))*n*m;
        PorihR(KilkistKolioriv)=t;
        t=256;
    end;
    t=t+1;
end;
end;

%Для цветовой G-составляющей изображения
LGmal=D(:,:,2);
HG=0;
HG=hist(LGmal(:),256);
PorihG=ones(1,rgb);
for KilkistKolioriv=1:rgb;
Htemp=0;
t=1;
while t<256;    
    Htemp=Htemp+HG(t);
    if Htemp>=(KilkistKolioriv/rgb-1/(2*rgb))*n*m;
        PorihG(KilkistKolioriv)=t;
        t=256;
    end;
    t=t+1;
end;
end;
 
%Для цветовой B-составляющей изображения
LBmal=D(:,:,3);
HB=0;
HB=hist(LBmal(:),256);
PorihB=ones(1,rgb);
for KilkistKolioriv=1:rgb;
Htemp=0;
t=1;
while t<256;
    Htemp=Htemp+HB(t);
    if Htemp>=(KilkistKolioriv/rgb-1/(2*rgb))*n*m;
        PorihB(KilkistKolioriv)=t;
        t=256;
    end;
    t=t+1;
end;
end;

Теперь значения интенсивностей цветовых составляющих пикселей данной локальной окрестности нужно модифицировать в соответствии с новыми градациями.

        [y NomerR]=min(abs(PorihR-Lr(i,j,1)));
        [y NomerG]=min(abs(PorihG-Lr(i,j,2)));
        [y NomerB]=min(abs(PorihB-Lr(i,j,3)));
        
        L1(i,j,1)=PorihR(NomerR);
        L1(i,j,2)=PorihG(NomerG);
        L1(i,j,3)=PorihB(NomerB);
          end;
  end;

Возвращаем изображение к исходным размерам

L1=L1(n1:n1+N,m1:m1+M,:);

и визуализируем результат

figure, imshow(L1./255);

В данном методе количество градаций и размер локальной апертуры могут быть различными. Поэтому продемонстрируем результаты, которые получены при разных количествах градаций цветовых составляющих и разных размерах локальных апертур.

Результат получен при двух градациях цветовых составляющих и размерах локальной апертуры 3×3.

Результат получен при семи градациях цветовых составляющих и размерах локальной апертуры 3×3.

Результат получен при пятнадцати градациях цветовых составляющих и размерах локальной апертуры 3×3.

Из проведенных экспериментов видно, что при увеличении количества градаций цветовых составляющих результат визуально улучшается. Однако в областях изображения с почти одинаковыми значениями интенсивности данный метод дает некорректный результат.

Увеличение размеров локальной апертуры приводит к улучшению работы метода в областях с почти одинаковыми значениями интенсивности. Так при пятнадцати градациях цветовых составляющих и размерах локальной апертуры 7х7 получим результат, который представлен на изображении внизу.

 

Метод 3. Суть следующего метода состоит в том, что модификации будут подвергаться не отдельные цветовые составляющие, а одновременно будет модифицирован весь вектор значений цветовых составляющих. Для проведения таких преобразований сначала необходимо задать набор новых векторов значений цветовых составляющих. В данной реализации будут использованы векторы значений цветовых составляющих, которые соответствуют красному, зеленому, синему, черному и белому цветам. Критерием замены исходного вектора на новый будет минимальное расстояние между этими векторами в пространстве RGB.

Рассмотрим программную реализацию этого метода боле подробно.

Сначала считываем исходное изображение в рабочее пространство Matlab и визуализируем его.

L=imread('im.bmp');
L=double(L(:,:,:));
figure, imshow(L./255);

Далее определяем размеры матрицы исходного файла и количество цветовых составляющих.

[N M k]=size(L);

После этого вычисляем расстояние в системе RGB между вектором значений пикселя исходного изображения и векторами значений для заданных цветов. Значения исходного вектора значений заменяются значениями того вектора, который в системе RGB расположен наиболее близко к исходному.

for i=1:N;
    disp(i);
     for j=1:M;
         %Красный цвет
         a(1)=sqrt((L(i,j,1)-255)^2+(L(i,j,2)-0)^2+(L(i,j,3)-0)^2);
         %Зеленый цвет
         a(2)=sqrt((L(i,j,1)-0)^2+(L(i,j,2)-255)^2+(L(i,j,3)-0)^2);
         %Синий цвет
         a(3)=sqrt((L(i,j,1)-0)^2+(L(i,j,2)-0)^2+(L(i,j,3)-255)^2);
         %Черный цвет
         a(4)=sqrt((L(i,j,1)-0)^2+(L(i,j,2)-0)^2+(L(i,j,3)-0)^2);
         %Белый цвет
         a(5)=sqrt((L(i,j,1)-255)^2+(L(i,j,2)-255)^2+(L(i,j,3)-255)^2);
         [y nomer]=min(a);
         if nomer==1; 
             L(i,j,1)=255;L(i,j,2)=0;L(i,j,3)=0;
         end;
         if nomer==2; 
             L(i,j,1)=0;L(i,j,2)=255;L(i,j,3)=0;
         end; 
         if nomer==3; 
             L(i,j,1)=0;L(i,j,2)=0;L(i,j,3)=255;             
         end;
         if nomer==4; 
             L(i,j,1)=0;L(i,j,2)=0;L(i,j,3)=0;
         end;
         if nomer==5; 
             L(i,j,1)=255;L(i,j,2)=255;L(i,j,3)=255;
         end;
                                       
     end;
  end;

Результат представлен на изображении внизу.

figure, imshow(L);

С точки зрения визуального восприятия результат не является наилучшим. Это можно объяснить тем, что набор выбранных цветов (красный, зеленый, синий, черный и белый) не был оптимальным. Поэтому для получения более приемлемого результата необходимо оптимизировать выбор набора цветов.

 

Метод 4. Этот метод является наиболее простым с точки зрения программной реализации. Его суть состоит в том, что значения интенсивностей пикселей будут округляться к тому или иному числу, значение которого будет зависеть, в том числе, от заданного количества цветов преобразованного изображения.

Сначала считываем изображение и визуализируем его.

L=imread('im.bmp');
L=double(L(:,:,:));
figure, imshow(L./255);

Далее необходимо задать количество градаций для каждой цветовой составляющей, которые будут использоваться при визуализации модифицированного изображения.

%Количество цветов
rgb=2;

Теперь будем выполнять модификацию значений интенсивностей пикселей в соответствии с изложенным выше подходом.

L=round(L./(256/(rgb-1))).*(256/(rgb-1));
figure, imshow(L./255);

Конечно, качество изображений, которые получены в результате таких преобразований, напрямую зависит от количества использованных градаций. Внизу приведены результаты преобразования при различных количествах градаций цветовых составляющих.

Результат получен при двух градациях цветовых составляющих.

Результат получен при семи градациях цветовых составляющих.

Результат получен при пятнадцати градациях цветовых составляющих.

Анализ рассмотренных нами методов уменьшения цветов на изображении позволяет сделать следующие выводы:

  1. Уменьшение количества цветов всегда приводит к потере визуального качества изображения.
  2. Более корректно обрабатывать не отдельные цветовые составляющие, поскольку это приводит к нарушению баланса цветности, а нужно анализировать и преобразовывать вектор цветов в целом.
  3. Эффективность решения задачи уменьшения количества цветов на изображении во многом зависит от цветовой гаммы исходного изображения.