1

I am working in image de-noising and therefore want to display an image as accurately as possible (e.g. before and after de-noising).

I have my grayscale image represented in a file with 256^2 = 65536 lines each with a floating point number between 0 and 1.

I could of course use any software to generate a picture from the data and save it under some format but I fear that I would always get a slight inaccuracy either by saving it or by putting the image into my tex with includegraphics.

Therefore I thought about actually plotting every pixel with TikZ. Is that possible/advisable?

EDIT: The file looks like this:

7.282250000000000112e-01
7.453062999999999771e-01
6.275306499999999676e-01
5.905055999999999639e-01
5.700786499999999091e-01
.
.
.

The first 256 lines make up the first row of pixels.

Franz
  • 175
  • 1
    Sure, that's possible. How is the data formatted exactly? Can you show us a snippet of your file? – Qrrbrbirlbel Sep 09 '22 at 11:47
  • I added details on the file. – Franz Sep 09 '22 at 12:24
  • 1
    you could plot with tikz but if you plotted to a lossless format such as PNG and included into latex without scaling it should be as accurate as anything else – David Carlisle Sep 09 '22 at 12:30
  • @DavidCarlisle I see. But I might want to scale the image. Maybe I am just confused how images work... How can I display a n-by-m pixel image on a quarter of my A4 pdf page without loss or interpolation on an a-priori unknown display that has k-by-l pixels? Probably I am making this to hard on myself. – Franz Sep 09 '22 at 12:41
  • I don't think TikZ can help with your unknown display. Both the PNG as well as the TikZ-generated picture will be rendered and displayed by the PDF software and the OS and the mentioned display. Have you tried exporting your image as a PNG and including it in your document? How does it look when scaled up? Does it get interpolated? (Try with a picture that has maybe only blacks and whites.) – Qrrbrbirlbel Sep 09 '22 at 12:58
  • I'm also working on image processing and my advice would be to use .png for the image itself (axis, labels etc. can be overlays as vector graphic and/or with tex). Drawing each pixel separately (as it is done in vector graphics) will blow up the file size very fast and pdf viewer have all kinds of "helpful" features, like thin line enhancement, which will mess with the result. – samcarter_is_at_topanswers.xyz Sep 09 '22 at 13:13
  • OK ty all. I will do some tests with png. – Franz Sep 09 '22 at 13:32
  • If you place an image with \includegraphics in your file, it will be printed "as is". If you scale it, no interpolation will be happening and there won't be any loss of the pixel data of the file, it will just be scaled. So, if you have a PNG of 10 pixels width and you scale this PNG to a width of 10 centimeters, each pixel will be 1 cm wide. – Jasper Habicht Sep 09 '22 at 15:35

1 Answers1

1

You could just place the image into your file using \includegraphics and scale it. There won't be any loss of data or interpolation happening.

If you, for whatever reason, still would like to recreate the image pixel by pixel using TikZ, you could do as follows:

\documentclass[border=10Mm]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.18}

\begin{filecontents}{image.dat} 7.282250000000000112e-01 7.453062999999999771e-01 6.275306499999999676e-01 5.905055999999999639e-01 5.700786499999999091e-01 0.25 0.75 0.25 0.75 0.25 0.75 0.25 0.75 0.25 0.75 \end{filecontents}

\pgfplotstableread{image.dat}{\pixeldata} % change to the name of the file

\def\pixelwidth{5} % change to width of image in pixels

\begin{document} \begin{tikzpicture}

\pgfplotstablegetrowsof{\pixeldata} \pgfmathsetmacro{\datarows}{\pgfplotsretval-1} \foreach \i in {0,...,\datarows} { \pgfplotstablegetelem{\i}{[index]0}\of{\pixeldata} \pgfmathsetmacro{\pixelvalue}{\pgfplotsretval100} \fill[black!\pixelvalue] ({mod(\i,\pixelwidth)},{-1floor(\i/\pixelwidth)}) rectangle +(1,1); }

\end{tikzpicture} \end{document}

Given that you have a list with the grayscale values of the pixels of your image, where 1 means black and 0 means white, and that you know the width of the image (256 pixels in your case), you can simply iterate over the list and draw a rectangle that is filled with the relevant gray value. You need to tell TeX the width of the image, of course. You can set the macro \pixelwidth to the width of the image in pixels in the above code (256 in your case).

In the code above, I added some more pixels to show how everything is supposed to work. The output of the above code looks like this (1 pixel = 1 centimeter):

enter image description here