为了账号安全,请及时绑定邮箱和手机立即绑定

如何将RGB图像转换为灰度,但保留一种颜色?

如何将RGB图像转换为灰度,但保留一种颜色?

如何将RGB图像转换为灰度,但保留一种颜色?我试图创造一个类似于罪恶之城或其他电影,他们删除所有的颜色,但一个从图像中删除。我有一个RGB图像,我想转换为灰度,但我想保留一种颜色。这是我的照片:我想保留红色。剩下的应该是灰阶的。到目前为止,这就是我的代码输出的内容(您可以看到这些区域是正确的,我不知道为什么它们是白色的,而不是红色的):到目前为止,这是我的代码:filename = 'roses.jpg';[cdata,map] = imread( filename );% convert to RGB if it is indexed imageif ~isempty( map )     cdata = idx2rgb( cdata, map ); end%imtool('roses.jpg');imWidth = 685;imHeight = 428;% RGB ranges of a color we want to keepredRange     = [140 255];greenRange = [0 40];blueRange = [0 40];% RGB values we don't want to convert to grayscaleredToKeep =      zeros(imHeight, imWidth);greenToKeep = zeros(imHeight, imWidth);blueToKeep = zeros(imHeight, imWidth);for x=1:imWidth     for y=1:imHeight         red = cdata( y, x, 1 );         green = cdata( y, x, 2 );         blue = cdata( y, x, 3 );         if (red >= redRange(1) && red <= redRange(2) && green >= greenRange(1) && green <= greenRange(2) && blue >= blueRange(1) &         & blue <= blueRange(2))             redToKeep( y, x ) = red;             greenToKeep( y, x ) = green;             blueToKeep( y, x ) = blue;         else             redToKeep( y, x ) = 999;             greenToKeep( y, x ) = 999;             blueToKeep( y, x ) = 999;         end     end end im = rgb2gray(cdata);[X, map] = gray2ind(im);im = ind2rgb(X, map);for x=1:imWidth     for y=1:imHeight         if (redToKeep( y, x ) < 999)             im( y, x, 1 ) = 240;         end         if (greenToKeep( y, x ) < 999)             im( y, x, 2 ) = greenToKeep( y, x );         end         if (blueToKeep( y, x ) < 999)             im( y, x, 3 ) = blueToKeep( y, x );         end     end end imshow(im);
查看完整描述

3 回答

?
慕仙森

TA贡献1827条经验 获得超7个赞

figurepic = imread('EcyOd.jpg');for mm = 1:size(pic,1)
    for nn = 1:size(pic,2)
        if pic(mm,nn,1) < 80 || pic(mm,nn,2) > 80 || pic(mm,nn,3) > 100
            gsc = 0.3*pic(mm,nn,1) + 0.59*pic(mm,nn,2) + 0.11*pic(mm,nn,3);
            pic(mm,nn,:) = [gsc gsc gsc];
        end
    endendimshow(pic)


查看完整回答
反对 回复 2019-07-10
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

一个大大提高图像质量的选择是转换到一个不同的颜色空间,以便更容易地选择您的颜色。特别是,HSV颜色空间定义像素颜色的色调(颜色)、饱和度(颜色的数量)和值(颜色的亮度)。

例如,可以使用以下函数将rgb图像转换为hsv空间。rgb2hsv,查找具有要定义为“非红色”颜色的像素(例如,20到340度),将这些像素的饱和度设置为0(因此它们是灰度),然后使用该函数将图像转换回rgb空间。hsv2rgb:

cdata = imread('EcyOd.jpg');       % Load imagehsvImage = rgb2hsv(cdata);         
% Convert the image to HSV spacehPlane = 360.*hsvImage(:, :, 1);   % Get the hue plane scaled from 0 to 360sPlane = hsvImage(:, :, 2);        
% Get the saturation planenonRedIndex = (hPlane > 20) & ...  % Select "non-red" pixels
              (hPlane < 340);sPlane(nonRedIndex) = 0;           
              % Set the selected pixel saturations to 0hsvImage(:, :, 2) = sPlane;        
              % Update the saturation planergbImage = hsv2rgb(hsvImage);      
              % Convert the image back to RGB space

下面是产生的图像:

注意,与塞勒斯的溶液,你可以很容易地保持花上淡粉色的色调。还请注意,褐色色调的茎和地面也消失了。

关于根据图像颜色属性从图像中选择对象的一个很酷的示例,您可以查看SteveEddins的博客文章。两个伙伴它描述了一种来自MathWorks的BrettShoelson的解决方案,用于从图像中提取一个“朋友”。


关于选择颜色范围的注意事项.。

另外一件可以帮助你选择颜色范围的事情是查看颜色的直方图。hPlane)出现在HSV图像的像素中。下面是一个使用函数的示例histc(或建议histcounts(如有的话)和bar:

binEdges = 0:360;    % Edges of histogram binshFigure = figure();  
% New figure% Bin pixel hues and plot histogram:if verLessThan('matlab', '8.4')
  N = histc(hPlane(:), binEdges);  % Use histc in older versions
  hBar = bar(binEdges(1:end-1), N(1:end-1), 'histc');else
  N = histcounts(hPlane(:), binEdges);
  hBar = bar(binEdges(1:end-1), N, 'histc');endset(hBar, 'CData', 1:360, ...            % Change the color of the bars using
          'CDataMapping', 'direct', ...  %   indexed color mapping (360 colors)
          'EdgeColor', 'none');          %   and remove edge coloringcolormap(hsv(360));                     
           % Change to an HSV color map with 360 pointsaxis([0 360 0 max(N)]);                 
            % Change the axes limitsset(gca, 'Color', 'k');                 
             % Change the axes background colorset(hFigure, 'Pos', [50 400 560 200]);   
             % Change the figure sizexlabel('HSV hue (in degrees)');          
             % Add an x labelylabel('Bin counts');                   
              % Add a y label

下面是得到的像素颜色直方图:

注意原始图像是如何包含红色、绿色和黄色像素的(有几个橙色像素)。几乎没有青色、蓝色、靛蓝色或品红色像素。还请注意,我在上面选择的范围(20到340度)很好地排除了大部分不是两端两个大的红色星系团的一部分的东西。


查看完整回答
反对 回复 2019-07-10
?
开满天机

TA贡献1786条经验 获得超12个赞

我真的不知道MATLAB是如何工作的,所以我不能对代码进行评论,但这可能有助于解释RGB颜色是如何工作的。

当使用RGB颜色时,可以通过确保R、G和B的值都相同来确定灰度。因此,基本上您想要做的是检测一个像素是否是红色的,当不只是使R、G和B相同时(您可以使用3的平均值来表示一个基本的结果)。

更难的部分是如何检测一个像素是否实际上是红色的,您不能仅仅检查一个像素在R值中是否高,因为它仍然可以是另一种颜色,而低的R值只意味着更深的红色。

所以您可以这样做:(我没有MATLAB,所以假设语法):

red = cdata( y, x, 1 );
green = cdata( y, x, 2 );
blue = cdata(y, x, 3);

if (red < (blue * 1.4) || red < (green * 1.4) )
{
    avg = (red + green + blue) / 3;
    cdata(y, x, 1) = avg;
    cdata(y, x, 2) = avg;
    cdata(y, x, 3) = avg;
}

也许有更好的方法来检测红色和平均灰度,但这是一个开始;)


查看完整回答
反对 回复 2019-07-10
  • 3 回答
  • 0 关注
  • 903 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信