una saber rgb2gray reconocimiento negro imagen grises esta escala descomponer crear convertir como colores color blanco matlab image-processing colors rgb grayscale

matlab - saber - ¿Cómo puedo convertir una imagen RGB a escala de grises pero mantener un solo color?



reconocimiento de colores rgb matlab (3)

Intento crear un efecto similar a Sin City u otras películas donde eliminan todos los colores, excepto uno de una imagen.

Tengo una imagen RGB que quiero convertir a escala de grises, pero quiero mantener un solo color.

Esta es mi foto:

Quiero mantener el color rojo El resto debe ser en escala de grises.

Esto es lo que mi código produce hasta ahora (se puede ver que las áreas son correctas, no sé por qué son blancas en lugar de rojas):

Aquí está mi código hasta ahora:

filename = ''roses.jpg''; [cdata,map] = imread( filename ); % convert to RGB if it is indexed image if ~isempty( map ) cdata = idx2rgb( cdata, map ); end %imtool(''roses.jpg''); imWidth = 685; imHeight = 428; % RGB ranges of a color we want to keep redRange = [140 255]; greenRange = [0 40]; blueRange = [0 40]; % RGB values we don''t want to convert to grayscale redToKeep = 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);


Realmente no sé cómo funciona Matlab, así que no puedo comentar el código, pero quizás esto ayude a explicar un poco cómo funcionan los colores RGB.

Al usar colores RGB, se puede hacer una escala de grises asegurándose de que los valores para R, G y B sean todos iguales. Entonces, básicamente, lo que quieres hacer es detectar si un píxel es rojo, cuando no solo haces R, G y B iguales (puedes usar un promedio de 3 para obtener un resultado rudimentario).

La parte más difícil es cómo detectar si un píxel es realmente rojo, no se puede simplemente verificar si un píxel es alto en el valor R, ya que todavía puede ser de otro color, y un valor bajo de R solo puede significar un rojo más oscuro.

entonces podrías hacer algo como esto: (No tengo matlab, así que supongo sintaxis):

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; }

Probablemente haya mejores formas de detectar rojo y obtener un gris promedio, pero es un comienzo;)


Una opción que mejora en gran medida la calidad de la imagen resultante es convertirla en un espacio de color diferente para seleccionar más fácilmente sus colores. En particular, el espacio de color HSV define los colores de los píxeles en términos de su tono (el color), la saturación (la cantidad de color) y el valor (el brillo del color).

Por ejemplo, puede convertir su imagen RGB al espacio HSV usando la función rgb2hsv , buscar píxeles con matices que abarcan lo que quiere definir como colores "no rojos" (como, por ejemplo, 20 grados a 340 grados), establecer la saturación para esos píxeles a 0 (para que sean en escala de grises), luego hsv2rgb nuevo a espacio RGB usando la función hsv2rgb :

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

Y aquí está la imagen resultante:

Observe cómo, en comparación con la solución de zellus , puede mantener fácilmente los tonos rosas claros en las flores. Observe también que los tonos marrones en el tallo y en el suelo también desaparecen.

Para un buen ejemplo de selección de objetos de una imagen en función de sus propiedades de color, puede consultar la publicación del blog de Steve Eddins The Two Amigos, que describe una solución de Brett Shoelson en MathWorks para extraer un "amigo" de una imagen.


Una nota sobre cómo seleccionar rangos de color ...

Una cosa más que puede hacer que puede ayudarlo a seleccionar rangos de colores es mirar un histograma de los matices (es decir, hPlane desde arriba) presente en los píxeles de su imagen HSV. Aquí hay un ejemplo que usa las funciones histc (o los histcounts recomendados, si están disponibles) y la bar :

binEdges = 0:360; % Edges of histogram bins hFigure = 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''); end set(hBar, ''CData'', 1:360, ... % Change the color of the bars using ''CDataMapping'', ''direct'', ... % indexed color mapping (360 colors) ''EdgeColor'', ''none''); % and remove edge coloring colormap(hsv(360)); % Change to an HSV color map with 360 points axis([0 360 0 max(N)]); % Change the axes limits set(gca, ''Color'', ''k''); % Change the axes background color set(hFigure, ''Pos'', [50 400 560 200]); % Change the figure size xlabel(''HSV hue (in degrees)''); % Add an x label ylabel(''Bin counts''); % Add a y label

Y aquí está el histograma de color de píxeles resultante:

Observe cómo la imagen original contiene principalmente píxeles de color rojo, verde y amarillo (con algunos de color naranja). Casi no hay píxeles de color cian, azul, índigo o magenta. Observe también que los rangos que seleccioné arriba (20 a 340 grados) hacen un buen trabajo al excluir casi todo lo que no es parte de los dos grandes grupos rojos en cada extremo.


figure pic = 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 end end imshow(pic)