tikz - dibuja el modelo 3d del espacio de color RGB-YUV

tikz - dibuja el modelo 3d del espacio de color RGB-YUV

Deseo dibujar un modelo de espacio de color 3D RGB-YUV. que se parece a continuación:

ingrese la descripción de la imagen aquí

El espacio de color del cubo RGB (0,255), la fórmula de conversión de RGB a YUV es:

ingrese la descripción de la imagen aquí

Fórmula de YUV a RGB:

ingrese la descripción de la imagen aquí

Deseo obtener un gráfico exacto como indica la fórmula. ¿Qué paquete quizás sea mejor para dibujar ese diagrama?

Respuesta1

Sí, se puede enseñar a Ti.kZ para hacer transformaciones lineales. Su captura de pantalla muestra una proyección no ortográfica. Así que agrego esa proyección al final de la respuesta, aunque personalmente no me gustan demasiado. Agregué una función RGBvecque realiza la transformación lineal (errores tipográficos de módulo porque no soy bueno ingresando textos de una pantalla, en particular cuando no sé de dónde vienen estas cosas), y agregué un estilo rápido que transforma las coordenadas RGB en el otro esquema de color. Todas estas cosas se pueden ajustar, pero al menos esto muestra cómo se puede hacer en principio.

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\def\matCC{{0.257, 0.504, 0.098},% 
        {-0.148, -0.291, 0.439},%
        {0.439, -0.368,0.071}}%
\pgfmathdeclarefunction{RGBvec}{3}{%
\begingroup%
\pgfmathsetmacro{\myY}{16+{\matCC}[0][0]*#1+{\matCC}[0][1]*#2+{\matCC}[0][2]*#3}%
\pgfmathsetmacro{\myCb}{128+{\matCC}[1][0]*#1+{\matCC}[1][1]*#2+{\matCC}[1][2]*#3}%
\pgfmathsetmacro{\myCr}{128+{\matCC}[2][0]*#1+{\matCC}[2][1]*#2+{\matCC}[2][2]*#3}%
\edef\pgfmathresult{\myCr,\myCb,\myY}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%

\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[bullet/.style={circle,inner
    sep=2pt,fill},line cap=round,line join=round,
    RGB coordinate/.code args={(#1,#2,#3)}{\pgfmathparse{RGBvec(#1,#2,#3)}%
    \tikzset{insert path={(\pgfmathresult)}}},font=\sffamily,thick]
 \begin{scope}[tdplot_main_coords,scale=1/40]
  \draw[-stealth] (0,0,0) coordinate (O) -- (280,0,0) coordinate[label=below:Cr] (Cr);
  \draw[-stealth]  (O) -- (0,280,0) coordinate[label=below:Cb] (Cb);
  \draw[-stealth]  (O) -- (0,0,280) coordinate[label=left:Y] (Y);
  \path [RGB coordinate={(255,255,255)}] node[bullet,draw,fill=white] (white){}
    [RGB coordinate={(0,0,0)}] node[bullet] (black){}
    [RGB coordinate={(255,0,0)}] node[bullet,red] (red){}
    [RGB coordinate={(0,255,0)}] node[bullet,green] (green){}
    [RGB coordinate={(0,0,255)}] node[bullet,blue] (blue){}
    [RGB coordinate={(255,0,255)}] node[bullet,magenta] (magenta){}
    [RGB coordinate={(255,255,0)}] node[bullet,yellow] (yellow){}
    [RGB coordinate={(0,255,255)}] node[bullet,cyan] (cyan){};
   \draw (red) -- (black) -- (blue) -- (magenta) -- (red) -- (yellow) 
   -- (green) edge (black) -- (cyan) edge (blue) -- (white)  edge (magenta) -- (yellow); 
   \draw[thin] (255,0,0) node[left]{255} -- (255,255,0) -- (0,255,0) node[above]{255}
   (0,0,255) node[left]{255} -- (255,0,255) edge (255,0,0)
    -- (255,255,255)  edge (255,255,0) -- (0,255,255)  edge (0,255,0)
   -- cycle ;
 \end{scope}
 \begin{scope}[xshift=8cm,scale=1/40]
  \pgfmathdeclarefunction*{RGBvec}{3}{%
  \begingroup%
  \pgfmathsetmacro{\myY}{16+{\matCC}[0][0]*#1+{\matCC}[0][1]*#2+{\matCC}[0][2]*#3}%
  \pgfmathsetmacro{\myCb}{128+{\matCC}[1][0]*#1+{\matCC}[1][1]*#2+{\matCC}[1][2]*#3}%
  \pgfmathsetmacro{\myCr}{128+{\matCC}[2][0]*#1+{\matCC}[2][1]*#2+{\matCC}[2][2]*#3}%
  \edef\pgfmathresult{\myCb,\myY,\myCr}%
  \pgfmathsmuggle\pgfmathresult\endgroup%
  }%
  \draw[-stealth] (0,0,0) coordinate (O) -- (255,0,0) coordinate[label=below:Cb] (Cb);
  \draw[-stealth]  (O) -- (0,255,0) coordinate[label=left:Y] (Y);
  \draw[-stealth]  (O) -- (0,0,255) coordinate[label=below:Cr] (Cr);
  \path [RGB coordinate={(255,255,255)}] node[bullet,draw,fill=white] (white){}
    [RGB coordinate={(0,0,0)}] node[bullet] (black){}
    [RGB coordinate={(255,0,0)}] node[bullet,red] (red){}
    [RGB coordinate={(0,255,0)}] node[bullet,green] (green){}
    [RGB coordinate={(0,0,255)}] node[bullet,blue] (blue){}
    [RGB coordinate={(255,0,255)}] node[bullet,magenta] (magenta){}
    [RGB coordinate={(255,255,0)}] node[bullet,yellow] (yellow){}
    [RGB coordinate={(0,255,255)}] node[bullet,cyan] (cyan){};
   \draw (red) -- (black) -- (blue) -- (magenta) -- (red) -- (yellow) 
   -- (green) edge (black) -- (cyan) edge (blue) -- (white)  edge (magenta) -- (yellow); 
  \end{scope}   
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Las proyecciones ortográficas tienen la ventaja de que se pueden aplicar transformaciones ortogonales, es decir, rotaciones, y el resultado es realista (hasta efectos de perspectiva, que se pueden solucionar utilizando la perspectivebiblioteca).

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\def\matCC{{0.257, 0.504, 0.098},% 
        {-0.148, -0.291, 0.439},%
        {0.439, -0.368,0.071}}%
\pgfmathdeclarefunction{RGBvec}{3}{%
\begingroup%
\pgfmathsetmacro{\myY}{16+{\matCC}[0][0]*#1+{\matCC}[0][1]*#2+{\matCC}[0][2]*#3}%
\pgfmathsetmacro{\myCb}{128+{\matCC}[1][0]*#1+{\matCC}[1][1]*#2+{\matCC}[1][2]*#3}%
\pgfmathsetmacro{\myCr}{128+{\matCC}[2][0]*#1+{\matCC}[2][1]*#2+{\matCC}[2][2]*#3}%
\edef\pgfmathresult{\myCr,\myCb,\myY}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\tikzset{RGB coordinate/.code args={(#1,#2,#3)}{\pgfmathparse{RGBvec(#1,#2,#3)}%
    \tikzset{insert path={(\pgfmathresult)}}}}
\begin{document}
\foreach \X in {0,10,...,350}
{\tdplotsetmaincoords{70}{\X}
\begin{tikzpicture}[bullet/.style={circle,inner
    sep=2pt,fill},line cap=round,line join=round,font=\sffamily,thick]
 \path[use as bounding box] (-5.5,-2)   rectangle (5.5,8);
 \begin{scope}[tdplot_main_coords,scale=1/40,shift={(-128,-128,0)}]
  \draw[-stealth] (0,0,0) coordinate (O) -- (280,0,0) coordinate[label=below:Cr] (Cr);
  \draw[-stealth]  (O) -- (0,280,0) coordinate[label=below:Cb] (Cb);
  \draw[-stealth]  (O) -- (0,0,280) coordinate[label=left:Y] (Y);
  \path [RGB coordinate={(255,255,255)}] node[bullet,draw,fill=white] (white){}
    [RGB coordinate={(0,0,0)}] node[bullet] (black){}
    [RGB coordinate={(255,0,0)}] node[bullet,red] (red){}
    [RGB coordinate={(0,255,0)}] node[bullet,green] (green){}
    [RGB coordinate={(0,0,255)}] node[bullet,blue] (blue){}
    [RGB coordinate={(255,0,255)}] node[bullet,magenta] (magenta){}
    [RGB coordinate={(255,255,0)}] node[bullet,yellow] (yellow){}
    [RGB coordinate={(0,255,255)}] node[bullet,cyan] (cyan){};
   \draw (red) -- (black) -- (blue) -- (magenta) -- (red) -- (yellow) 
   -- (green) edge (black) -- (cyan) edge (blue) -- (white)  edge (magenta) -- (yellow); 
   \draw[thin] (255,255,0) -- (255,0,0) node[pos=1.1]{255} 
   (255,255,0) --(0,255,0) node[pos=1.1]{255}
   (0,0,255) node[left]{255} -- (255,0,255) edge (255,0,0)
    -- (255,255,255)  edge (255,255,0) -- (0,255,255)  edge (0,255,0)
   -- cycle ;
 \end{scope}
\end{tikzpicture}}
\end{document}

ingrese la descripción de la imagen aquí

Por supuesto, también se pueden hacer que las conexiones presenten transiciones de color.

\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\def\matCC{{0.257, 0.504, 0.098},% 
        {-0.148, -0.291, 0.439},%
        {0.439, -0.368,0.071}}%
\pgfmathdeclarefunction{RGBvec}{3}{%
\begingroup%
\pgfmathsetmacro{\myY}{16+{\matCC}[0][0]*#1+{\matCC}[0][1]*#2+{\matCC}[0][2]*#3}%
\pgfmathsetmacro{\myCb}{128+{\matCC}[1][0]*#1+{\matCC}[1][1]*#2+{\matCC}[1][2]*#3}%
\pgfmathsetmacro{\myCr}{128+{\matCC}[2][0]*#1+{\matCC}[2][1]*#2+{\matCC}[2][2]*#3}%
\edef\pgfmathresult{\myCr,\myCb,\myY}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\tikzset{RGB coordinate/.code args={(#1,#2,#3)}{\pgfmathparse{RGBvec(#1,#2,#3)}%
    \tikzset{insert path={(\pgfmathresult)}}}}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[bullet/.style={circle,inner
    sep=2pt,outer sep=0pt,fill},connection bar/.style args={(#1)--(#2)}{%
    insert path={let \p1=(#1),\p2=(#2),\n1={atan2(\y2-\y1,\x2-\x1)} in 
    [left color=#1,right color=#2,shading angle=\n1+90]
    (#1.\n1-25) arc(\n1-25:\n1+25:40*2pt) 
    -- (#2.\n1-180-25)  arc(\n1-180-25:\n1-180+25:40*2pt) -- cycle}},
    line cap=round,line join=round,font=\sffamily,thick]
 \path[use as bounding box] (-5.5,-2)   rectangle (5.5,8);
 \begin{scope}[tdplot_main_coords,scale=1/40,shift={(-128,-128,0)}]
  \draw[-stealth] (0,0,0) coordinate (O) -- (280,0,0) coordinate[label=below:Cr] (Cr);
  \draw[-stealth]  (O) -- (0,280,0) coordinate[label=below:Cb] (Cb);
  \draw[-stealth]  (O) -- (0,0,280) coordinate[label=left:Y] (Y);
  \path [RGB coordinate={(255,255,255)}] node[bullet,draw,fill=white] (white){}
    [RGB coordinate={(0,0,0)}] node[bullet] (black){}
    [RGB coordinate={(255,0,0)}] node[bullet,red] (red){}
    [RGB coordinate={(0,255,0)}] node[bullet,green] (green){}
    [RGB coordinate={(0,0,255)}] node[bullet,blue] (blue){}
    [RGB coordinate={(255,0,255)}] node[bullet,magenta] (magenta){}
    [RGB coordinate={(255,255,0)}] node[bullet,yellow] (yellow){}
    [RGB coordinate={(0,255,255)}] node[bullet,cyan] (cyan){};
  \path[connection bar={(black)--(blue)}];
  \path[connection bar={(blue)--(magenta)}];
  \path[connection bar={(magenta)--(red)}];
  \path[connection bar={(red)--(black)}];
  \path[connection bar={(white)--(magenta)}];
  \path[connection bar={(cyan)--(blue)}];
  \path[connection bar={(green)--(black)}];
  \path[connection bar={(yellow)--(red)}];
  \path[connection bar={(yellow)--(green)}];
  \path[connection bar={(green)--(cyan) }];
  \path[connection bar={(cyan)--(white)}];
  \path[connection bar={(white)--(yellow)}];
   \draw[thin] (255,255,0) -- (255,0,0) node[pos=1.1]{255} 
   (255,255,0) --(0,255,0) node[pos=1.1]{255}
   (0,0,255) node[left]{255} -- (255,0,255) edge (255,0,0)
    -- (255,255,255)  edge (255,255,0) -- (0,255,255)  edge (0,255,0)
   -- cycle ;
 \end{scope}
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Algunas observaciones:

  1. En principio, hay una forma mucho más sencilla de realizar una transformación lineal: , \begin{scope}[x={(x)},y={(y)},x={(y)}] ... \end{scope}donde (x)y son los vectores base. Pero con el cambio adicional las cosas se vuelven un poco confusas y pensé que tener las coordenadas explícitamente podría tener sentido.(y)(z)
  2. \pgfshadecolortorgbpermite convertir un color en coordenadas RGB. Al escribir esta publicación, no había pensado en usarlo.

Respuesta2

Un punto de partida. Ahora puedes dibujar en coordenadas 3D. Mirando tu perfil, creo que puedes hacerlo.

\documentclass[tikz,margin=3]{standalone}
\usetikzlibrary{arrows.meta}
\begin{document}
\begin{tikzpicture}[z={(-135:.5)},>=Stealth]
  \draw[thick,->] (0,0,0) -- (5,0,0) node[below] {Cb};
  \draw[thick,->] (0,0,0) -- (0,5,0) node[left] {Y};
  \draw[thick,->] (0,0,0) -- (0,0,5) node[below] {Cr};
  \draw (4,0,0) node[anchor=135] {255} |- (0,4,0) node[anchor=-30] {255} 
    -- (0,4,4) |- (4,0,4) -- cycle
    (0,4,4) -| (4,0,4) (4,4,4) -- (4,4,0)
    (0,0,4) node[anchor=-30] {255};
  \path (0,0) node[below] {0};
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

información relacionada