如何在不使用循环的情况下从Matlab RGB图像帧中删除不需要的颜色

如何在不使用循环的情况下从Matlab RGB图像帧中删除不需要的颜色,matlab,colors,rgb,Matlab,Colors,Rgb,我有一个RGB图像帧,我想删除所有不是所需颜色的像素 如果没有for循环,如何实现这一点 % Desired color: R 105, G 112, B 175 % I want to zero all pixels that are not this color (plus a tad). red_target = 105; green_target = 112; blue_target = 175; tad = 4;

我有一个RGB图像帧,我想删除所有不是所需颜色的像素

如果没有for循环,如何实现这一点

    % Desired color:   R 105, G 112, B 175
            % I want to zero all pixels that are not this color (plus a tad).

    red_target = 105;
    green_target  = 112;
    blue_target = 175;

    tad = 4;
    red_low = red_target - tad;
    red_hi = red_target + tad;
    green_low = green_target - tad;
    green_hi = green_target + tad;
    blue_low = blue_target - tad;
    blue_hi = blue_target + tad;


    % Filter out non-target colors:
    % Pixel redness is within target; greenness is within target; and blueness within:
    % Reset pixel if wrong redness OR wrong greenness OR wrong blueness:
    raw_frame_size = size( raw_frame )
    rows = raw_frame_size( 1 );
    columns = raw_frame_size( 2 );
    for row = 1:rows
        for column = 1:columns
            % Reset RGB pixel value if pixel is outside desired range:
            pixel_redness =  raw_frame(row,column,1);
            pixel_greenness =  raw_frame(row,column,2);
            pixel_blueness =  raw_frame(row,column,3);
            if  (      ( pixel_redness < red_low )  |  ( pixel_redness > red_hi ) ...
                    |  ( pixel_greenness < green_low )  |  ( pixel_greenness > green_hi  ) ...
                    |  ( pixel_blueness < blue_low )  |  ( pixel_blueness > blue_hi ) ) 
                raw_frame( row, column, 1 ) = 0;
                raw_frame( row, column, 2 ) = 0;
                raw_frame( row, column, 3 ) = 0;

            end
        end
    end
%所需颜色:R105、G112、B175
%我想把所有不是这种颜色的像素归零(加上一点)。
红色目标=105;
绿色目标=112;
蓝色目标=175;
tad=4;
红色低=红色目标-tad;
红色高=红色目标+tad;
绿色低=绿色目标-tad;
绿色高=绿色目标+tad;
蓝色低=蓝色目标-tad;
蓝色高=蓝色目标+tad;
%过滤掉非目标颜色:
%像素红色在目标范围内;绿色度在目标范围内;以及内在的蓝色:
%如果红色或绿色错误或蓝色错误,则重置像素:
原始帧大小=大小(原始帧)
行=原始帧大小(1);
列=原始帧大小(2);
对于行=1:行
对于列=1:列
%如果像素超出所需范围,则重置RGB像素值:
像素红度=原始帧(行、列、1);
像素绿色度=原始帧(行、列、2);
像素蓝度=原始帧(行、列、3);
如果((像素红度<红度低)|(像素红度>红度高)。。。
|(像素绿色度<绿色度低)|(像素绿色度>绿色度高)。。。
|(像素_蓝度<蓝色_低)|(像素_蓝度>蓝色_高))
原始帧(行、列、1)=0;
原始帧(行、列、2)=0;
原始帧(行、列、3)=0;
结束
结束
结束

没有for循环就无法完成。
下面是我使用for循环的解决方案

    % blue:   R 105, G 112, B 175

    red_target = 105;
    green_target  = 112;
    blue_target = 175;

    tad = 20;
    red_low = red_target - tad;
    red_hi = red_target + tad;
    green_low = green_target - tad;
    green_hi = green_target + tad;
    blue_low = blue_target - tad;
    blue_hi = blue_target + tad;


    % Filter out non-target colors:
    % Pixel redness is within target; greeness is within target; and blueness within:
    % Reset pixel if wrong redness OR wrong greenness OR wrong blueness:

    raw_frame_size = size( raw_frame )
    rows = raw_frame_size( 1 );
    columns = raw_frame_size( 2 );
    for row = 1:rows
        for column = 1:columns
            % Reset RGB pixel value if pixel is outside desired range:
            pixel_redness =  raw_frame(row,column,1);
            pixel_greenness =  raw_frame(row,column,2);
            pixel_blueness =  raw_frame(row,column,3);
            if  (      ( pixel_redness < red_low )  |  ( pixel_redness > red_hi ) ...
                    |  ( pixel_greenness < green_low )  |  ( pixel_greenness > green_hi  ) ...
                    |  ( pixel_blueness < blue_low )  |  ( pixel_blueness > blue_hi ) ) 
                raw_frame( row, column, 1 ) = 0;
                raw_frame( row, column, 2 ) = 0;
                raw_frame( row, column, 3 ) = 0;

            end
        end
    end
%blue:R105、G112、B175
红色目标=105;
绿色目标=112;
蓝色目标=175;
tad=20;
红色低=红色目标-tad;
红色高=红色目标+tad;
绿色低=绿色目标-tad;
绿色高=绿色目标+tad;
蓝色低=蓝色目标-tad;
蓝色高=蓝色目标+tad;
%过滤掉非目标颜色:
%像素红色在目标范围内;绿色在目标范围内;以及内在的蓝色:
%如果红色或绿色错误或蓝色错误,则重置像素:
原始帧大小=大小(原始帧)
行=原始帧大小(1);
列=原始帧大小(2);
对于行=1:行
对于列=1:列
%如果像素超出所需范围,则重置RGB像素值:
像素红度=原始帧(行、列、1);
像素绿色度=原始帧(行、列、2);
像素蓝度=原始帧(行、列、3);
如果((像素红度<红度低)|(像素红度>红度高)。。。
|(像素绿色度<绿色度低)|(像素绿色度>绿色度高)。。。
|(像素_蓝度<蓝色_低)|(像素_蓝度>蓝色_高))
原始帧(行、列、1)=0;
原始帧(行、列、2)=0;
原始帧(行、列、3)=0;
结束
结束
结束

从我所能看出的是您的目标,对于使用逻辑索引的
循环,这在没有
的情况下是绝对可以实现的

% Prepare Filter Arrays.
imageSize = size ( raw_frame );
filterArray  = zeros ( imageSize ( 1 ) , imageSize ( 2 ) );

% Identify filter pixels.
% This step utilizes logical indexing.
filterArray ( raw_frame(:,:,1) < red_low ) = 1;
filterArray ( raw_frame(:,:,1) > red_high ) = 1;
filterArray ( raw_frame(:,:,2) < green_low ) = 1;
filterArray ( raw_frame(:,:,2) > green_high ) = 1;
filterArray ( raw_frame(:,:,3) < blue_low ) = 1;
filterArray ( raw_frame(:,:,3) > blue_high) = 1;

% Replicate the array to 3D.
filter3d = repmat ( filterArray , [ 1 1 3 ]);

% Filter the image.
% This step also uses logical indexing.
raw_frame ( filter3d ) = 0;
%准备过滤器阵列。
图像大小=大小(原始帧);
filterArray=零(imageSize(1),imageSize(2));
%识别过滤器像素。
%此步骤利用逻辑索引。
过滤器阵列(原始帧(:,:,1)<红色低)=1;
过滤器阵列(原始帧(:,:,1)>红色帧高)=1;
过滤器阵列(原始帧(:,:,2)<绿色低)=1;
过滤器阵列(原始帧(:,:,2)>绿色高)=1;
过滤器阵列(原始帧(:,:,3)<蓝色低)=1;
过滤器阵列(原始帧(:,:,3)>蓝色高)=1;
%将阵列复制到3D。
filter3d=repmat(filterArray[13]);
%过滤图像。
%此步骤还使用逻辑索引。
原始帧(filter3d)=0;
此外,由于无法单独使用RGB值将颜色从饱和度和黑暗中分离出来,因此使用RGB图像执行颜色过滤通常是一种不好的做法

例如,RGB值[100,80,40]和[50,40,20]是相同的颜色(色调),但强度不同(亮度或值)。更好的选择可能是:

targetRgb(1,1,1) = 105;
targetRgb(1,1,2) = 112;
targetRgb(1,1,3) = 175;
targetHsv = rgb2hsv(targetRgb);

frameHsv = rgb2hsv(raw_frame);
frameSize = size(raw_frame);

hTad = 0.05;

% Values must be in the range [0,1] inclusive.
% Because "hue" is a "colorwheel", -0.3 would be the same value as 0.7.
targetHLow = ( targetHsv(1) - hTad + 1 ) - floor ( targetHsv(1) - hTad + 1);

% A value like 1.3 is the same  as 0.3
targetHHigh = ( targetHsv(1) + hTad ) - floor ( targetHsv(1) + hTad );

% Create the filter.
hFilter = zeros(frameSize(1),frameSize(2));
hFilter(hFilter<targetHLow) = 1;
hFilter(hFilter>targetHHigh) = 1;

% Zero out the value channel.
frameV = framHsv(:,:,3);
frameV(hFilter) = 0;
frameHsv(:,:,3) = frameV;

% Convert the modified HSV back to RGB.
frameFiltered = hsv2rgb(frameHsv);    
targetRgb(1,1,1)=105;
targetRgb(1,1,2)=112;
targetRgb(1,1,3)=175;
targetHsv=rgb2hsv(targetRgb);
frameHsv=rgb2hsv(原始帧);
frameSize=大小(原始帧);
hTad=0.05;
%值必须在[0,1]范围内(含0,1)。
%因为“色调”是“色轮”,所以-0.3与0.7的值相同。
targetHsv=(targetHsv(1)-hTad+1)-地板(targetHsv(1)-hTad+1);
%类似于1.3的值与0.3的值相同
targetHHigh=(targetHsv(1)+hTad)-地板(targetHsv(1)+hTad);
%创建过滤器。
hFilter=0(帧大小(1),帧大小(2));
高频滤波器(高频滤波器目标高)=1;
%将值通道归零。
frameV=framHsv(:,:,3);
frameV(hFilter)=0;
frameHsv(:,:,3)=frameV;
%将修改后的HSV转换回RGB。
frameFiltered=hsv2rgb(frameHsv);

我认为有一个更简单、计算效率更高的实现。过滤器是一个2D逻辑阵列

myrgb = rand(100,100,3);
imagesc(myrgb)
floatNorm = 2^8 - 1;
tad = repmat(4, [100, 100, 3]);
target = repmat([105,112,175], 100*100, 1);
target = reshape(target, [100, 100, 3]);
threshold = (target + tad)/floatNorm;
myFilt = abs(myrgb - 1/2) <= threshold;
myrgb(myFilt) = 0;
imagesc(myrgb)
myrgb=rand(100100,3);
imagesc(myrgb)
floatNorm=2^8-1;
tad=repmat(4[100100,3]);
target=repmat([105112175],100*100,1);
目标=重塑(目标[100100,3]);
阈值=(目标+tad)/NORM;

myFilt=abs(myrgb-1/2)看看这个,然后做相反的事情:另外,要小心使用
&
。我认为您的代码中缺少一些
&
。完成。我介绍了如何使用for循环,我希望用最少数量的语句替换它。@DougNull-再次。。。看看这个帖子:。。。然后做相反的操作。@DougNull-那篇文章根本没有对
循环使用
。它将图像转换为HSV,并在选择要保持的颜色的主要色调时进行一些巧妙的选择。在您的情况下,您希望执行相反的操作并删除该domi