00001 # -*- coding: utf-8 -*- 00002 00003 import math 00004 00005 ## @package face_contour_detector.image_information.image_information 00006 # This module provides class to extract information from an image (class ImageInformation and InformationExtractor). 00007 # There are also basic information extractor implementations: SizeExtractor, MinMaxExtractor, AverageValueExtractor 00008 # @author Fabian Wenzelmann 00009 00010 ## @brief This class is an abstract class that defines methods to extract informatioon from an image (CvMat). 00011 # @author Fabian Wenzelmann 00012 # @date 2011-02-20 00013 # 00014 # For this we suppose the image to be in RGB format were the blue component is the first componenent, green the second and red the third (as in OpenCv, whyever).<br> 00015 # There is only one method required: extract_information(). See extract_information() for further explanation.<br> 00016 # Extracting information from an image is done by calling the extract_information() method for this image. 00017 # We assume the image to be "big enough". This means that there are more than two pixel in each image so that we can use values like \f$ \frac{1}{n-1} \f$ where n is the number of pixel. 00018 # Usually complete white pixels are ignored since we assume that they're white because this part of the image was not covered by the mask image. 00019 class ImageInformation: 00020 ## @brief For a given image (as CvMat in RGB format) extract whatever kind of information. 00021 # @param self the object pointer 00022 # @param img the image as CvMat in RGB format 00023 # 00024 # Extract the information from the image. Return value is a <i>list</i>. This list contains <i>three tuples</i>. Such a tuple <i>t</i> has the form t = (name, value, type). Where <i>name</i> is the name of the property t represents for example MaxPixelValue. <i>value</i> is the value of this property for example 200 if 200 is the maximal pixel value in img. <i>type</i> is a string and is one of "int", "float", "string". These tuples can be added to xml_image_information. 00025 def extract_information(self, img): 00026 raise NotImplementedError("Subclasses of ImageInformation must implement the method extract_information(image)") 00027 00028 ## @brief Subclass of ImageInformation that extracts height and width value (names "Height" and "Width"), both of type int 00029 # @author Fabian Wenzelmann 00030 # @date 2011-02-20 00031 class SizeExtractor(ImageInformation): 00032 ## Constructor method 00033 # @param self the object pointer 00034 def __init__(self): 00035 pass 00036 00037 def extract_information(self, img): 00038 return [ ( "Height", img.height, "int" ), ("Width", img.width, "int") ] 00039 00040 ## @brief Subclass of ImageInformation that extracts min / max pixel values from image. 00041 # @author Fabian Wenzelmann 00042 # @date 2011-02-20 00043 # 00044 # For each color component there is a min / max component so it returns a list with 6 three tuples. The max value of the red component has the name MaxR and so on. All values are of tpye int. 00045 class MinMaxExtractor(ImageInformation): 00046 ## Constructor method 00047 # @param self the object pointer 00048 def __init__(self): 00049 pass 00050 00051 def extract_information(self, img): 00052 first = img[0, 0] 00053 r_max = r_min = first[2] 00054 g_max = g_min = first[1] 00055 b_max = b_min = first[0] 00056 width_range = range(img.width) 00057 for row in range(img.height): 00058 for col in width_range: 00059 pixel = img[row, col] 00060 if pixel == (255, 255, 255): 00061 continue 00062 r = pixel[2] 00063 g = pixel[1] 00064 b = pixel[0] 00065 r_max = max(r_max, r) 00066 r_min = min(r_min, r) 00067 g_max = max(g_max, g) 00068 g_min = min(g_min, g) 00069 b_max = max(b_max, b) 00070 b_min = min(b_min, b) 00071 return [ ("MaxR", r_max, "float"), ("MinR", r_min, "float"), ("MaxG", g_max, "float"), ("MinG", g_min, "float"), ("MaxB", b_max, "float"), ("MinB", b_min, "float") ] 00072 00073 ## @brief Subclass of ImageInformation which extracts several average values. 00074 # @author Fabian Wenzelmann 00075 # @date 2011-02-20 00076 # 00077 # For each pixel the brightness is defined as \f$ red * 0.299 + green * 0.587 + blue * 0.114\f$. The average of all those values is returned. Name is "AveragePixelBrightness". 00078 # Also calculates for each color channel the average value. For them the names are for example "AverageR" for the red color channel. Also calculates three standard deviation values (for each component one). 00079 # The names are "StandardDeviationR" and so on. Also (last also) returns "StandardBrightnessDeviation" All returned values are of type float. 00080 class AverageValueExtractor(ImageInformation): 00081 ## Constructor method 00082 # @param self the object pointer 00083 def __init__(self): 00084 pass 00085 00086 def extract_information(self, img): 00087 value_sum = 0.0 00088 value_squared_sum = 0.0 00089 00090 r_sum = 0.0 00091 g_sum = 0.0 00092 b_sum = 0.0 00093 00094 r_square_sum = 0.0 00095 g_square_sum = 0.0 00096 b_square_sum = 0.0 00097 pixel_count = 0 00098 width_range = range(img.width) 00099 for row in range(img.height): 00100 for col in width_range: 00101 pixel = img[row, col] 00102 if pixel == (255, 255, 255): 00103 continue 00104 pixel_count += 1 00105 blue = pixel[0] 00106 green = pixel[1] 00107 red = pixel[2] 00108 brightness = red * 0.299 + green * 0.587 + blue * 0.114 00109 value_sum += brightness 00110 value_squared_sum += brightness ** 2 00111 r_sum += red 00112 g_sum += green 00113 b_sum += blue 00114 00115 r_square_sum += red ** 2 00116 g_square_sum += green ** 2 00117 b_square_sum += blue ** 2 00118 standard_derivation_r = math.sqrt( max( (1.0 / (pixel_count - 1)) * (r_square_sum - ((1.0 / pixel_count) * r_sum ** 2)), 0)) 00119 standard_derivation_g = math.sqrt( max( (1.0 / (pixel_count - 1)) * (g_square_sum - ((1.0 / pixel_count) * g_sum ** 2)), 0)) 00120 standard_derivation_b = math.sqrt( max( (1.0 / (pixel_count - 1)) * (b_square_sum - ((1.0 / pixel_count) * b_sum ** 2)), 0)) 00121 standard_derivation_brightness = math.sqrt( max( (1.0 / (pixel_count - 1)) * (value_squared_sum - ((1.0 / pixel_count) * value_sum ** 2)), 0)) 00122 return [ ("AveragePixelBrightness", value_sum / pixel_count, "float"), ("AverageR", r_sum / pixel_count, "float"), ("AverageG", g_sum / pixel_count, "float"), ("AverageB", b_sum / pixel_count, "float"), ("StandardDeviationR", standard_derivation_r, "float"), ("StandardDeviationG", standard_derivation_g, "float"), ("StandardDeviationB", standard_derivation_b, "float"), ("StandardBrightnessDeviation", standard_derivation_brightness, "float") ] 00123 00124 ## @brief This class is used to extract information from an image using ImageInformation subclasses 00125 # @author Fabian Wenzelmann 00126 class InformationExtractor: 00127 ## @brief Constructor method 00128 # @param self the object pointer 00129 def __init__(self): 00130 self.information_extractors = [] 00131 00132 # field documentation 00133 ## @var information_extractors 00134 # a list of objects of type ImageInformation. In this list all extractors are stored. 00135 00136 ## @brief add ImageInformation objects for classes SizeExtractor, MinMaxExtractor, AverageValueExtractor 00137 # @param self the object pointer 00138 def add_default_extractors(self): 00139 e1 = SizeExtractor() 00140 e2 = MinMaxExtractor() 00141 e3 = AverageValueExtractor() 00142 self.information_extractors += [e1, e2, e3] 00143 00144 ## @brief Create a dictionary using the ImageInformation instances stored in self.information_extractors. 00145 # @param self the object pointer 00146 # @param img the image to collect the information from as cvMat with RGB colors. 00147 # 00148 # All ImageInformation subclasses return in their extract_information() method tuples of names and values. The dictionary uses the names as keys and stores the information as tuples: (value, type) 00149 def to_dict(self, img): 00150 properties = {} 00151 for extractor in self.information_extractors: 00152 res = extractor.extract_information(img) 00153 for name, value, name_type in res: 00154 properties[name] = value, name_type 00155 return properties