2

I open a pgm file, convert it to numPy array and change all pixels to 0 or 1 (or 255, I don't know how to proceed yet). How can I save it as .PBM using openCV?

Like:

P1
512 512
0 1 0 0 0 . .
0 0 0 1 0 . .
. . . . . . .
. . . . . . . 
. . . . . . . 

Thanks in advance!

Davi Stuart
  • 269
  • 3
  • 16

2 Answers2

2
vector<int> params;
params.push_back(CV_IMWRITE_PXM_BINARY);
params.push_back(0); // 1 for binary format, 0 for ascii format
imwrite("image.pbm", image, params); // the .pbm extension specifies the encoding format
Sergei Nosov
  • 1,637
  • 11
  • 9
  • 1
    `cv2.imwrite("image.pbm", image, (cv2.IMWRITE_PXM_BINARY, 0))` writes PGM format, not PBM. – cgohlke Oct 01 '13 at 18:35
  • Yeah, cgohlke's right, the call writes the PGM format. But the only distinction from the PBM is the header (P2 instead of P1) in case you have only 0-1 values. Is that the only problem, or something else doesn't work? – Sergei Nosov Oct 02 '13 at 06:35
  • 2
    By checking the OpenCV 2.4.6.1 source code, I think it can never produce a 'P4' PBM header, therefore it doesn't actually support PBM format. – tomriddle_1234 Oct 29 '13 at 23:35
1

Using OpenCV seems overkill. Just open a file and write the header and image data. Plain PBM is very inefficient. Consider Raw PBM (magic number P4) instead. E.g. for Python 2.7:

with open('image.pbm', 'wb') as fd:
    fd.write("P4\n%i %i\n" % image.shape[::-1])
    numpy.packbits(image, axis=-1).tofile(fd)

For plain PBM:

with open('image.pbm', 'w') as fd:
    fd.write("P1\n%i %i\n" % image.shape[::-1])
    fd.write("\n".join(" ".join(str(i) for i in j) for j in image))

image is a 2D binary valued numpy array.

cgohlke
  • 9,142
  • 2
  • 33
  • 36