9

I have a question.

I am performing a series of operations (resize, copy, etc.) to some captured images in OpenCV, but I want to set some specific metadata (the attribute names should also be defined by me) to these images, which would survive those operations and can be extracted later on. I am not setting resolution values or any other value that changes after these operations. How can I do this? I heard of pyexiv2, but I have never seen any example involving OpenCV.

Thanks in advance!

Subhamoy S.
  • 6,566
  • 10
  • 37
  • 53
  • We all have questions on here:-) I take it you are talking about adding metadata at the point of writing out the image to file? OpenCV (including version 2.3.1 - the very latest) has always provided it's image I/O via the "HighGUI" library. So you can at least write a .jpg, .png, .tiff. etc. However, the concept of metadata attached to the internal image class - the underlying IplImage - prior to this does not exist. Consequently you'll have to write any EXIF data _post hoc_ to the file. – timlukins Mar 27 '12 at 12:44
  • P.S. In which case you are probably right about using pyexiv2. As per previous Q: http://stackoverflow.com/questions/765396/exif-manipulation-library-for-python – timlukins Mar 27 '12 at 12:47

1 Answers1

4

So, ultimately, you could just facade the 2 file contents (data and metadata) behind your own python class:

import cv 
import pyexiv2

class MyImage():

  _filename = None
  _data = None
  _metadata = None

  def __init__(self,fname):

    _filename = fname
    _data = cv.LoadImage(_filename)
    _metadata = pyexiv2.ImageMetadata(_filename)
    _metadata.read()

  def addMeta(self,key,value):
    _metadata[key] = pyexiv2.ExifTag(key, value)

  def delMeta(self,delkey):
    newdict = {key: value for key, value in some_dict.items()
                if value is not delkey}

  def resize(self,newx,newy):
    tmpimage = cv.CreateMat(newy, newx, cv.CV_8UC3)
    cv.Resize(_data,tmpimage)
    _data = tmpimage
    try: # Set metadata tags to new size if exist!
      _metadata['Exif.Image.XResolution'] = newx
      _metadata['Exif.Image.YResolution'] = newy
    except:
      pass

  def save(self):
    cv.SaveImage(_filename,_data) 
    _metadata.write()
timlukins
  • 2,694
  • 21
  • 35
  • 1
    Thank you for such a nice response! The only problem with using a format like ttf or jpg is, I am not saving the images anywhere. They are being grabbed, transfered over a network connection, displayed, and that's all. I tried `cv2.imencode()` but due to some kind of bug, it does not produce JPEG. The only way is to convert to cvMat and use legacy method `cv.EncodeImage()`, which would not preserve the metadata any more. – Subhamoy S. Mar 28 '12 at 14:35
  • 1
    Ah - I believe I see your problem. Even if you use the PIL [Image](http://www.pythonware.com/library/pil/handbook/image.htm) class `fromBuffer()` method you can at least create an image in memory even from the OpenCV raw data. However, it seems you can't then create/update new EXIF tags via `PIL.ExifTags`...:-( See [here](http://stackoverflow.com/questions/400788/resize-image-in-python-without-losing-exif-data). – timlukins Mar 28 '12 at 16:25