我正在使用以下代码生成一个填充随机值的矩阵。我想用这个矩阵来解释如何将卷积应用于图像(特别是平均值),所以我试图用它填充输出矩阵。我无法重复使用列表中的值来用于 pgfmath 计算,这是此方法不起作用的主要原因。任何帮助都非常感谢!
谢谢大家。
% tikzpic.tex
\documentclass[crop,tikz]{standalone}% 'crop' is the default for v1.0, before it was 'preview'
\usetikzlibrary{calc,matrix,positioning,backgrounds,fit}
\usepackage{listofitems}
\setsepchar{;/,}
\begin{document}
\begin{tikzpicture}[
DA/.style={
fill,
opacity=0.2,
%rounded corners,
inner sep=-1pt,
line width=1pt,
},
]
\readlist\image{%
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult,\pgfmathparse{random(0,255)}\pgfmathresult;
}
\matrix [matrix of math nodes,left delimiter={[},right delimiter={]}] (im) {
\image[1,1] &\image[1,2] &\image[1,3] &\image[1,4] &\image[1,5] &\image[1,6] &\image[1,7]\\
\image[2,1] &\image[2,2] &\image[2,3] &\image[2,4] &\image[2,5] &\image[2,6] &\image[2,7]\\
\image[3,1] &\image[3,2] &\image[3,3] &\image[3,4] &\image[3,5] &\image[3,6] &\image[3,7]\\
\image[4,1] &\image[4,2] &\image[4,3] &\image[4,4] &\image[4,5] &\image[4,6] &\image[4,7]\\
\image[5,1] &\image[5,2] &\image[5,3] &\image[5,4] &\image[5,5] &\image[5,6] &\image[5,7]\\
\image[6,1] &\image[6,2] &\image[6,3] &\image[6,4] &\image[6,5] &\image[6,6] &\image[6,7]\\
\image[7,1] &\image[7,2] &\image[7,3] &\image[7,4] &\image[7,5] &\image[7,6] &\image[7,7]\\
};
\node[right=.2em of im] (str) {\(\ast\)};
\matrix (k) [matrix of math nodes,left delimiter={[},right delimiter={]}, right=.2em of str] {
\frac{1}{9}&\frac{1}{9}&\frac{1}{9} \\
\frac{1}{9}&\frac{1}{9}&\frac{1}{9} \\
\frac{1}{9}&\frac{1}{9}&\frac{1}{9} \\
};
\node[right=.2em of k] (eq) {\(=\)};
\matrix (imp) [matrix of math nodes,left delimiter={[},right delimiter={]}, right=.2em of eq] {
1 & 4 & 3 & 4 & 1\\
1 & 2 & 4 & 3 & 3\\
1 & 2 & 3 & 4 & 1\\
1 & 3 & 3 & 1 & 1\\
3 & 3 & 1 & 1 & 0\\
};
\node[below=0.2em of im] (imlabel) {\(i_{mn}\)};
\node (klabel) at (k|-imlabel) {\(k_{pq}\)};
\node (conv) at (str|-imlabel) {\(\ast\)};
\node (eqlabel) at (eq|-imlabel) {\(=\)};
\node (implabel) at (imp|-imlabel) {\({im'}_{mn}\)};
\begin{scope}[on background layer]
\node[DA,blue,fit=(im-1-4)(im-3-6)](im_sub){};
\node[DA,purple,fit=(imp-1-4)(imp-1-4)](imp_sub){};
\node[DA,red,fit=(k-1-1)(k-3-3)](k_sub){};
\end{scope}
\draw[dashed, teal] (im_sub.north east) -- (k_sub.north west);
\draw[dashed, teal] (im_sub.south east) -- (k_sub.south west);
\draw[dashed, blue!80!black] (k_sub.north east) -- (imp_sub.north west);
\draw[dashed, blue!80!black] (k_sub.south east) -- (imp_sub.south west);
\end{tikzpicture}
\end{document}
答案1
这是一个使用 PGFMath 数组的 PGFmath 和\fpeval
解决方案(仅用于将九个数字相加并除以 9)。
但是,由于我让 PGFmath 评估了该数组一次(因为我们想要固定数字),因此它不再以逗号分隔列表(逗号分隔列表)的形式存储,而是以其内部格式(使用括号对项目进行分组)存储。\pgfmatharray@
不幸的是,要再次访问它,我们需要使用。
这是通过\pgfmathtwoarray
以下方式完成的:不是可扩展但返回结果\pgfmathresult
。这可用于打印或在内部使用\fpeval
。
我已经调整了矩阵的一些设置,以便分隔符能够更漂亮地放置在矩阵周围。
anchor=base east
可以通过使用矩阵内的节点并用填充小数位0
(通过 PGFmath 或siunitx
或...)来实现数字的水平对齐。
为了更容易访问这 49 个值,我只需将它们存储在宏/值键中,就可以直接通过它们的索引访问它们,但这是一种完全不同的方法。
虽然\fpeval
支持元组,但我在手册中没有看到有关访问其值的任何信息。这可能需要l3fparray
/l3intarray
来提供对其数组值的可扩展访问。
代码
\documentclass[tikz]{standalone}
% \usepackage{xfp}% possibly necessary for older distributions
\usetikzlibrary{calc,matrix,positioning,backgrounds,fit}
\makeatletter
\newcommand*\repeatMe[2]{%
\ifnum#1=0 \expandafter\@gobble\else\expandafter\@firstofone\fi
{#2\expandafter\repeatMe\expandafter{\the\numexpr#1-1\relax}{#2}}}
\newcommand*\pgfmathtwoarray[3]{
\pgfmatharray@{#1}{\pgfinteval{#2-1}}%
\pgfmatharray@{\pgfmathresult}{\pgfinteval{#3-1}}}
\newcommand*\tikzbuildmatrix[3]{%
\repeatMe{#1}{%
\repeatMe{#2}{%
\node[name=\tikzmatrixname-\the\pgfmatrixcurrentrow-\the\pgfmatrixcurrentcolumn]{#3};
\unless\ifnum\pgfmatrixcurrentcolumn=#1 \expandafter\pgfmatrixnextcell\fi}
\unless\ifnum\pgfmatrixcurrentrow=#2 \expandafter\pgfmatrixendrow\fi}
\pgfmatrixendrow}
\makeatother
\begin{document}
\begin{tikzpicture}[
DA/.style={
fill,
opacity=0.2,
%rounded corners,
inner sep=-1pt,
line width=1pt,
},
every left delimiter/.append style={xshift=.3333em},
every right delimiter/.append style={xshift=-.3333em},
every outer matrix/.append style={inner sep=+0pt},
]
\pgfmathsetmacro\image{{% this % is important here
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)},
{random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255),random(0,255)}}}
\matrix [left delimiter={[},right delimiter={]},nodes={anchor=base}] (im) {
\tikzbuildmatrix{7}{7}
{\pgfmathtwoarray{\image}{\pgfmatrixcurrentrow}{\pgfmatrixcurrentcolumn}\pgfmathresult}
};
\node[right=.2em of im] (str) {\(\ast\)};
\matrix (k) [left delimiter={[},right delimiter={]}, right=.2em of str] {
\tikzbuildmatrix{3}{3}{$\frac{1}{9}$}};
\node[right=.2em of k] (eq) {\(=\)};
\matrix (imp) [matrix of math nodes,left delimiter={[},right delimiter={]}, right=.2em of eq,
row 1 column 4/.style={nodes={fill=purple!20, alias=imp_sub}}] {
\tikzbuildmatrix{5}{5}{
\gdef\solution{0}%
\foreach[expand list] \ROW in {\pgfmatrixcurrentrow,...,\inteval{\pgfmatrixcurrentrow+2}}{
\foreach[expand list] \COL in {\pgfmatrixcurrentcolumn,...,\inteval{\pgfmatrixcurrentcolumn+2}}{
\pgfmathtwoarray{\image}{\ROW}{\COL}%
\xdef\solution{\fpeval{\solution+\pgfmathresult}}
}
}
\fpeval{round(\solution/9,2)}
}};
\node[below=0.2em of im] (imlabel) {\(i_{mn}\)};
\node (klabel) at (k|-imlabel) {\(k_{pq}\)};
\node (conv) at (str|-imlabel) {\(\ast\)};
\node (eqlabel) at (eq|-imlabel) {\(=\)};
\node (implabel) at (imp|-imlabel) {\({im'}_{mn}\)};
\begin{scope}[on background layer]
\node[DA,blue,fit=(im-1-4)(im-1-5)(im-1-6)(im-1-6)(im-2-6)(im-3-6)](im_sub){};
\node[DA,red,fit=(k-1-1)(k-3-3)](k_sub){};
\end{scope}
\draw[dashed, teal] (im_sub.north east) -- (k_sub.north west);
\draw[dashed, teal] (im_sub.south east) -- (k_sub.south west);
\draw[dashed, blue!80!black] (k_sub.north east) -- (imp_sub.north west);
\draw[dashed, blue!80!black] (k_sub.south east) -- (imp_sub.south west);
\end{tikzpicture}
\end{document}