001/* Change the contrast of an image. 002 @Copyright (c) 1998-2014 The Regents of the University of California. 003 All rights reserved. 004 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the 008 above copyright notice and the following two paragraphs appear in all 009 copies of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION 2 025 COPYRIGHTENDKEY 026 */ 027package ptolemy.domains.sdf.lib.vq; 028 029import ptolemy.actor.lib.Transformer; 030import ptolemy.data.IntMatrixToken; 031import ptolemy.data.type.BaseType; 032import ptolemy.kernel.CompositeEntity; 033import ptolemy.kernel.util.IllegalActionException; 034import ptolemy.kernel.util.NameDuplicationException; 035import ptolemy.kernel.util.Workspace; 036 037/////////////////////////////////////////////////////////////////// 038//// ImageContrast 039 040/** 041 Change the contrast of an image. 042 043 <p>If the input image has a lot of pixels with the same or similar color, 044 This actor uses gray scale equalization to redistribute the value of each 045 pixel between 0 and 255. 046 047 @author Michael Leung, Steve Neuendorffer 048 @version $Id$ 049 @since Ptolemy II 0.2 050 @Pt.ProposedRating Red (mikele) 051 @Pt.AcceptedRating Red (cxh) 052 */ 053public class ImageContrast extends Transformer { 054 /** Construct an actor with the given container and name. 055 * @param container The container. 056 * @param name The name of this actor. 057 * @exception IllegalActionException If the actor cannot be contained 058 * by the proposed container. 059 * @exception NameDuplicationException If the container already has an 060 * actor with this name. 061 */ 062 public ImageContrast(CompositeEntity container, String name) 063 throws IllegalActionException, NameDuplicationException { 064 super(container, name); 065 066 output.setTypeEquals(BaseType.INT_MATRIX); 067 input.setTypeEquals(BaseType.INT_MATRIX); 068 } 069 070 /////////////////////////////////////////////////////////////////// 071 //// public methods //// 072 073 /** Clone the actor into the specified workspace. 074 * @param workspace The workspace for the new object. 075 * @return A new actor. 076 * @exception CloneNotSupportedException If a derived class contains 077 * an attribute that cannot be cloned. 078 */ 079 @Override 080 public Object clone(Workspace workspace) throws CloneNotSupportedException { 081 ImageContrast newObject = (ImageContrast) super.clone(workspace); 082 newObject.colorHistogram = new int[256]; 083 return newObject; 084 } 085 086 /** Fire the actor. 087 * Consume one image on the input port. 088 * 089 * Summary: 090 * Contrast the image so that 091 * an more evenly color distributed image can be obtained. 092 * Assume that color is bounded from 0 to 255 inclusively. 093 * @exception IllegalActionException If image color is out-of-bound. 094 * 095 * Algorithm: 096 * Construct a color histogram for the input image. 097 * Construct a cdf for the color histogram. 098 * Using Gray Scale Equalization, re-map each image pixel color. 099 * 100 * Send the new image out the output port. 101 */ 102 @Override 103 public void fire() throws IllegalActionException { 104 super.fire(); 105 int i; 106 int j; 107 int[][] frame; 108 int frameElement; 109 110 IntMatrixToken message = (IntMatrixToken) input.get(0); 111 frame = message.intMatrix(); 112 113 // Construct a color distribution histogram for the input image: 114 // Assuming the color bound for the input 0 and 255. If color detected 115 // that has color either bigger than 255 OR small than 0, then throw an 116 // illegal action exception. 117 for (i = 0; i < 256; i++) { 118 colorHistogram[i] = 0; 119 } 120 121 int pixels = frame.length * frame[0].length; 122 123 for (i = 0; i < frame.length; i++) { 124 for (j = 0; j < frame[i].length; j++) { 125 frameElement = frame[i][j]; 126 127 if (frameElement < 0 || frameElement > 255) { 128 throw new IllegalActionException( 129 "ImageContrast:" + "input image pixel contains at" 130 + j + "," + i + "with value" + frameElement 131 + "that is out of bounds." 132 + " Not between 0 and 255."); 133 } 134 135 colorHistogram[frameElement]++; 136 } 137 } 138 139 //Construct the cdf of the color distribution histogram 140 //colorHistogram[0] = colorHistogram[0] 141 for (i = 1; i < 256; i++) { 142 colorHistogram[i] = colorHistogram[i - 1] + colorHistogram[i]; 143 } 144 145 // Search each pixel in the image and re-map it to a new 146 // color number to make a new relatively even color distribution 147 // image. 148 int distributionConstant = pixels / 255; 149 150 for (i = 0; i < frame.length; i++) { 151 for (j = 0; j < frame[i].length; j++) { 152 frameElement = frame[i][j]; 153 frame[i][j] = colorHistogram[frameElement] 154 / distributionConstant; 155 } 156 } 157 158 message = new IntMatrixToken(frame); 159 output.send(0, message); 160 } 161 162 /////////////////////////////////////////////////////////////////// 163 //// private variables //// 164 private int[] colorHistogram = new int[256]; 165}