zoukankan      html  css  js  c++  java
  • 基于RGB与HSI颜色模型的图像提取法

      现实中我们要处理的往往是RGB彩色图像。对其主要通过HSI转换、分量色差等技术来提出目标。

    RGB分量灰度化:

      RGB可以分为R、G、B三分量。当R=G=B即为灰度图像,很多时候为了方便,会直接利用某个分量来进行灰度化,如下图所示:

        上图中R分量下红色部分明显比其他两幅更偏白;同样地G分量草地较淡,B分量天空较淡。其他部分如灰黑色马路则相差不多。实际中,我们可以根据

      需求有选择地选择分量。

    RGB分量差灰度化:

      有时候我们的要求是从图像中提取某种颜色区域,那么最简单的方法就是采用RGB色差。

      例如在花束中提取红色的花瓣,就可以采用R-G分量差(目标为红色,干扰为G分量),或者,在土壤表面提取绿色秧苗,可以采用G-R-B分量差(G占2份,土壤可能

      存在R,B分量干扰),下图为提取结果:

      

      如果遇到更复杂的情况,可以根据目标颜色与干扰颜色设计合适的分量差。

      

    HSI分量灰度化:

        H、S、I分别表示色调、饱和度、明度。色调指日常所说的颜色(红,白,黑等),饱和度则表示颜色的鲜艳程度,值越大越鲜艳,明度则是颜色的明亮

      程度。这三种属性可以用两个椎体表示,其中明度是竖直中心轴,在竖直方向上,明度不同;每个明度对应一个横截面,用极坐标表示H,S,H为角度,S为模长。

      HSI模型如图所示:

      

      我们可以将RGB转为HSI,相关公式有很多种,各有特点,下面介绍其中一种:

        rgb_min=min(r,g,b)

        rgb_max=max(r,g,b)

        I=rgb_max

        S=(rgb_max-rgb_min)/rgb_max

        if r==rgb_max

          H=abs(g-b)/(rgb_max-rgb_min)/3

        if g==rgb_max

          H=1/3+abs(r-b)/(rgb_max-rgb_min)/3

        if  b==rgb_max

          H=2/3+abs(r-g)/(rgb_max-rgb_min)/3

      如此计算所得的H范围为[0,1),S范围为[0,1),I范围[0,255]。HSI分量灰度图如下:

      

      明度分量与一般灰度化效果差不多(可能灰度化可能是基于明度的),有时候利用饱和度与色调灰度号的图像进行提取会便利很多,如下图是基于饱和度的二值提取

      (一般如果要基于颜色提取的化采用RGB分量色差比较好,毕竟如果要获取较精准的饱和度信息,所用公式会比上面的复杂):

      

      由于背景的饱和度较低,而目标饱和度高,而且目标由多种颜色组成,这样如果直接基于明度的灰度化不可能提取到整个花束,而通过饱和度提取的效果就非常棒。

      另外,也可以将HSI组合起来使用,使得特征更明显,例如可以用饱和度与色调消除红眼现象,具体基于HSI的算法这里就不探究了!

    以上相关matlab仿真测试代码如下:

    %RGB分量差提取
    imga=imread('flower.jpg');
    imgb=imread('soil.jpg');
    imga2=uint8(zeros(300,300));
    imgb2=uint8(zeros(300,300));
    for i=1:300
        for j=1:300
            r=imga(i,j,1);
            g=imga(i,j,2);
            if (r>g)
                imga2(i,j)=uint8(r-g);
            else
                imga2(i,j)=0;
            end
        end
    end
    
    for i=1:300
        for j=1:300
            r=imgb(i,j,1);
            g=imgb(i,j,2);
            b=imgb(i,j,3);
            if 2*uint16(g)>(uint16(r)+uint16(b))
                imgb2(i,j)=uint8(2*uint16(g)-uint16(r)-uint16(b));
            else
                imgb2(i,j)=0;
            end
        end
    end
    
    imga2=imbinarize(imga2,60/255);
    imgb2=imbinarize(imgb2,40/255);
    
    subplot(2,2,1);
    imshow(imga);
    title('原图');
    subplot(2,2,2);
    imshow(imga2);
    title('R-G分量差提取红色部分');
    
    subplot(2,2,3);
    imshow(imgb);
    title('原图');
    subplot(2,2,4);
    imshow(imgb2);
    title('G-R-B分量差提取绿色部分');
    %RGB转HSI模型
    function myhsvdisplay(file)
        rgb=imread(file);
        [sizex,sizey,~]=size(rgb);
        
        hsv_v=uint8(zeros(sizex,sizey));
        hsv_s=double(zeros(sizex,sizey));
        hsv_h=double(zeros(sizex,sizey));
        for i=1:sizex
            for j=1:sizey
                r=rgb(i,j,1);
                g=rgb(i,j,2);
                b=rgb(i,j,3);
                rgb_min=min([r,g,b]);
                rgb_max=max([r,g,b]);
                hsv_v(i,j)=rgb_max;
                hsv_s(i,j)=(double(rgb_max)-double(rgb_min))/double(rgb_max);
                if r==rgb_max
                    hsv_h(i,j)=abs( double(g)-double(b))/(double(rgb_max)-double(rgb_min))/double(3);
                elseif g==rgb_max
                    hsv_h(i,j)=double(1/3)+abs(double(g)-double(b))/(double(rgb_max)-double(rgb_min))/double(3);
                else
                    hsv_h(i,j)=double(2/3)+abs(double(g)-double(b))/(double(rgb_max)-double(rgb_min))/double(3);
                end      
            end
        end
       
        subplot(2,2,1);
        imshow(rgb);
        title('rgb原图');
        
        subplot(2,2,2);
        imshow(hsv_v);
        title('明度信号');
        
        subplot(2,2,3);
        imshow(hsv_s);
        title('饱和度信号');
        
        subplot(2,2,4);
        imshow(hsv_h);
        title('色调信号');
    end
    %利用饱和度提取
    function sbinarize(file)
       imga=imread(file);
       [~,hsv_s,hsv_v]=rgb2hsv(imga);
       sbin=imbinarize(hsv_s,80/255);
       vbin=imbinarize(hsv_v,130/255);
        subplot(1,3,1);
        imshow(imga);
        title('原图');
        subplot(1,3,2);
        imshow(sbin);
        title('饱和度提取');
        subplot(1,3,3);
        imshow(vbin);
        title('明度提取');
    end

     

       

      

  • 相关阅读:
    body background bottom在firefox下的bug
    性能测试(并发负载压力)测试分析-简要篇 (转载)
    concurrent group
    分析性能数据(转载)
    关于并发测试的思考--交流贴
    Watir 试用手记——一个很不错的开源 Web 自动化测试框架(转)
    lr中winsock协议的脚本(转载51testing)
    英语常用问句(转)
    安装rpc的问题
    调整压力测试工具(转)--非常不错的文章
  • 原文地址:https://www.cnblogs.com/kensporger/p/11618520.html
Copyright © 2011-2022 走看看