如何从图像中删除所有黑色像素并仅使用图像中找到的唯一 RGB 值

How can I delete all black pixels from an image and only use the unique RGB values found in the image

如何从图像中删除所有黑色像素并仅使用在图像中找到的唯一 RGB 值

What I'm trying to do is: 
1) delete all black pixels from the image and only use the unique RGB colors found in the image
2) export each combined RGB color pixels that is unique as a separate 640x480 image 
3) Convert / join these images into a movie file.

我的想法是将我的红色、绿色和蓝色通道拆分为相应的颜色,并将它们重塑为三个数组,每个数组一列。 并开始删除黑色像素。

如何删除所有黑色单元格值(其中 R、G、B 通道为 0)并仅查找/使用唯一的 RGB 值

我附上了下面的图片和一段代码:

resize_tmp_red=reshape(fintersect_red',[1,1200*1200])(:); %will cause array to be created / reshaped left to right and top to bottom (like reading a book) into 1 column
resize_tmp_green=reshape(fintersect_green',[1,1200*1200])(:); 
resize_tmp_blue=reshape(fintersect_blue',[1,1200*1200])(:); 

%How can I delete all cell values that are black (where the R,G,B channels are 0) and only find / use the RGB values that are unique in the image

for cc=1:10

  repmat_rgb(:,:,1)=uint8(repmat(resize_tmp_red(cc,1),[640,480])); %creates 640x480 image of RGB taken from deleted black and unique color array.
  repmat_rgb(:,:,2)=uint8(repmat(resize_tmp_green(cc,1),[640,480]));
  repmat_rgb(:,:,3)=uint8(repmat(resize_tmp_blue(cc,1),[640,480]));

  %imshow(repmat_rgb)


  imwrite(repmat_rgb,strcat('/tmp/',sprintf('%03d', cc),'_img.png')); %creates image file

end

PS:我使用的是 Octave 4.0,它类似于 Matlab。 是的,我将不再看到原始图像的结构。我将仅使用图像中的独特颜色制作电影。

我不使用你在代码中输入的语言,但如果我在 c/c++ 中这样做,我会遍历数据并计算非黑色像素,创建一个新的该大小的数组,然后再次循环并将它们一一复制到新数组中。这能做到吗?

我不确定这是否是最好的方法,但你可以这样做:

R = double(im(:,:,1))*255*255;
G = double(im(:,:,2))*255;
B = double(im(:,:,3));
RGB = R+G+B; % Now you have 2D matrix

unq = sort(unique(RGB));
unq = unq(2:end); %remove (0,0,0)

B2 = rem(unq(:),255);
G2 = rem((unq-B2)/255,255);
R2 = (unq-G2*255 - B2)/255/255;
% You can make this part more efficient probably. and make sure there is no error

colors_you_want = [R2 G2 B2];

我所做的是,我将 3D 图像转换为 2D 双矩阵并找到所有独特的元素,即您想要的所有颜色。 unq 的第一个元素是 (0,0,0),所以我删除了那个。然后我转换回二维结构,其中 R 是第一列,G 是第二列,B 是第三列。

要找到黑色像素,您只需让所有三个颜色通道都为零即可。您可以告诉 sum 函数对第三个维度求和。如果三个通道都为零,则总和也为零。

im = imread('example.png');    
black_mask = sum(im, 3) == 0;

现在你有一个指示黑色像素的二维蒙版。下一步是构建掩码以访问每个通道中的所有其他像素

red_mask = ~cat(3, black_mask, ones(size(black_mask)), ones(size(black_mask)))); %The inverse of the black mask in the red channel and any pixel in all other channels
green_mask = ~cat(3, ones(size(black_mask)), black_mask, ones(size(black_mask))));%For the other channels just change the order.
blue_mask= ~cat(3, ones(size(black_mask)), ones(size(black_mask)), black_mask));

好的,现在我们可以从每个通道中获取值了。

red = im(red_mask);
blue = im(blue_mask);
green = im(green_mask);

并在三维中将它们连接起来制作图像

non_unique = cat(3, red, green, blue);

non_unique 是包含所有非黑色像素的图像。要获得唯一像素,您必须置换矩阵以使用 unique 的 'row' 选项。

non_unique = permute(non_unique, [1 3 2]);
output = unique(non_unique, 'rows'); %Get unique rows
output = permute(output, [1 3 2]); %Permute it back to recover color channels

输出图像为 1 像素宽和 94 像素长。要获得所需的 640x480 形状,您需要对其进行整形和调整大小。我找不到任何好的因子来获得所需的比率,所以我只使用了 94: 2 和 47 这两个最大的素因子。

reshaped_output = reshape(output, 2, 47, 3);
reshaped_output = imresize(reshaped_output, [480, 640]);

这是图像在各个步骤的比较。

正如您在评论中提到的,您想要一个具有独特颜色的输出二维矩阵,其中每一行都是一个 RGB 元组 没有 黑色像素。您可以做的是将 RGB 图像重塑为 2D 矩阵,其中每一列都是一个颜色通道,删除行完全为 0 的所有实例,然后 运行 通过 unique to remove the duplicates. To do this, you will need to perform a per channel transpose by using permute, then exploiting the order of the elements with reshape to finally create a 3 column matrix of RGB values. Once you do this, use any 找到所有具有至少一个值(即不是黑色像素),过滤掉矩阵中完全为零的行,然后最后使用 unique 但将其应用于行,以便每一行都被视为一个 "example" ,假设您的图像存储在 im:

像这样的东西会起作用:

% Reshape the RGB image into a 3 column matrix
R = reshape(permute(im, [2 1 3]), [], 3);

% Remove black pixels
R = R(any(R, 2), :);

% Remove duplicates
colours = unique(R, 'rows', 'stable');

colours 将是没有黑色的唯一颜色输出二维矩阵。请注意,我使用 'stable' 标志来维护遇到颜色的顺序。通过省略它,它将按输出中的行 sort 矩阵。正如您在评论中指出的那样,Octave 不支持此功能,因此如果您不关心订单,您可以删除 'stable' 标志,我相信在这种情况下您不需要,因为您只想要一个矩阵不包括黑色的独特颜色。

因此:

colours = unique(R, 'rows');