AttributeError with Python Enum

Problem

I had code that had worked correctly with Python 2.7 and that used the old enum module. Recently it started throwing this error:

$ ./foo.py 
Traceback (most recent call last):
  File "./foo.py", line 146, in <module>
    main()
  File "./foo.py", line 100, in draw_plot
    if PlotType.Line == plot_type:
  File "/usr/local/lib/python2.7/dist-packages/enum/__init__.py", line 373, in __getattr__
    raise AttributeError(name)
AttributeError: Line

Solution

This error is caused when the enum34 module has been installed alongside the old enum module. enum34 is the backport for Python 2.x of the standard enum in Python 3.4. Many packages have started to use it and so it will be installed implicitly while installing another package. enum34 overrides the old enum files and causes this error.

You could remove enum34 and get rid of this error. But since Python 3.x has already adapted a new enum type, it might be wiser to uninstall the old enum and rewrite your code to use enum34. Its syntax is shown in this example.

Tried with: Python 2.7.6 and Ubuntu 14.04

How to specify OpenCV color type in Python

Problem

OpenCV has bindings for Python. Specifying the color type in calls to imread or imdecode gives this error:

$ cat foo.py
import cv
import cv2
mat = cv2.imread("foo.png", cv.CV_LOAD_IMAGE_ANYCOLOR)

$ python foo.py
AttributeError: 'module' object has no attribute 'CV_LOAD_IMAGE_ANYCOLOR'

Solution

It looks like the CV_LOAD_IMAGE enums which specify the color type of an image have not been exported to Python. Thankfully, the integer value of these enums can be passed directly to the call.

This enum is defined in highgui/highgui_c.h as:

enum
{
/* 8bit, color or not */
    CV_LOAD_IMAGE_UNCHANGED  =-1,
/* 8bit, gray */
    CV_LOAD_IMAGE_GRAYSCALE  =0,
/* ?, color */
    CV_LOAD_IMAGE_COLOR      =1,
/* any depth, ? */
    CV_LOAD_IMAGE_ANYDEPTH   =2,
/* ?, any color */
    CV_LOAD_IMAGE_ANYCOLOR   =4
};

Make the call using the integer value of the enum directly:

# To call with CV_LOAD_IMAGE_ANYCOLOR
mat = cv2.imread("foo.png", 4)

Tried with: OpenCV 2.4.9, Python 2.7.6 and Ubuntu 14.04

Enum in C++

C++11 introduced a much better enumeration. It provides a named scope for its enumerators and is strongly typed:

enum class FileType
{
    Png,
    Jpg,
    Bmp
};

write_file(img_data, "foo", FileType::Jpg);

When using an older C++ compiler, I try to get the scope feature of C++11 by using a namespace:

namespace FileType
{
    enum Enum
    {
        Png,
        Jpg,
        Bmp
    };
}

// Excepts the type FileType::Enum
write_file(img_data, "foo", FileType::Jpg);

How to use enum in Python

Python 2.x does not have an equivalent of the enum in C or C++. Python 3.x (3.4 and later) has a builtin enum type.

You can install the backported Python 3.4 enum for Python 2.x easily from here:

$ sudo pip install enum34

Usage of this enum is simple:

from enum import Enum

class Colors(Enum):
    Red   = 1
    Green = 2
    Blue  = 3

c = Colors.Green

Tried with: Python 2.7.6 and Ubuntu 14.04