1 /** 2 * Copyright (c) 2011, The University of Southampton and the individual contributors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * * Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * * Neither the name of the University of Southampton nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 /** 31 * 32 */ 33 package org.openimaj.video.processing.shotdetector; 34 35 import org.openimaj.feature.DoubleFVComparison; 36 import org.openimaj.image.MBFImage; 37 import org.openimaj.image.analysis.algorithm.histogram.HistogramAnalyser; 38 import org.openimaj.math.statistics.distribution.Histogram; 39 import org.openimaj.video.Video; 40 41 /** 42 * Video shot detector class implemented as a video display listener. This 43 * means that shots can be detected as the video plays. The class also 44 * supports direct processing of a video file (with no display). The default 45 * shot boundary threshold is 5000 which is an unnormalised value and will 46 * depend on the frame size. 47 * <p> 48 * Only the last keyframe is stored during processing, so if you want to store 49 * a list of keyframes you must store this list yourself by listening to the 50 * ShotDetected event which provides a VideoKeyframe which has a timecode 51 * and an image. Each event will receive the same VideoKeyframe instance 52 * containing different information. USe VideoKeyframe#clone() to make a copy. 53 * 54 * @author David Dupplaw (dpd@ecs.soton.ac.uk) 55 * 56 * @created 1 Jun 2011 57 */ 58 public class HistogramVideoShotDetector 59 extends VideoShotDetector<MBFImage> 60 { 61 /** The previous frame's histogram */ 62 private Histogram lastHistogram; 63 64 /** 65 * If you use this constructor, your timecodes will be messed up 66 * unless you call {@link #setFPS(double)} before you process 67 * any frames. 68 */ 69 public HistogramVideoShotDetector() 70 { 71 this.threshold = 5000; 72 } 73 74 /** 75 * Constructor that takes the frame rate of the source material. 76 * @param fps The FPS 77 */ 78 public HistogramVideoShotDetector( final double fps ) 79 { 80 super( fps ); 81 this.threshold = 5000; 82 } 83 84 /** 85 * Default constructor takes the video to process. 86 * @param video The video 87 */ 88 public HistogramVideoShotDetector( final Video<MBFImage> video ) 89 { 90 super( video ); 91 this.threshold = 5000; 92 } 93 94 /** 95 * Constructor that determines whether to display the processing. 96 * @param video The video 97 * @param display Whether to display the video while processing 98 */ 99 public HistogramVideoShotDetector( final Video<MBFImage> video, final boolean display ) 100 { 101 super( video, display ); 102 this.threshold = 5000; 103 } 104 105 /** 106 * Checks whether a shot boundary occurred between the given frame 107 * and the previous frame, and if so, it will add a shot boundary 108 * to the shot boundary list. 109 * 110 * @param frame The new frame to process. 111 */ 112 @Override 113 protected double getInterframeDistance( final MBFImage frame ) 114 { 115 // Get the histogram for the frame. 116 final HistogramAnalyser hp = new HistogramAnalyser( 64 ); 117 if( frame instanceof MBFImage ) 118 hp.analyseImage( frame.getBand(0) ); 119 final Histogram newHisto = hp.getHistogram(); 120 121 double dist = 0; 122 123 // If we have a last histogram, compare against it. 124 if( this.lastHistogram != null ) 125 dist = newHisto.compare( this.lastHistogram, DoubleFVComparison.EUCLIDEAN ); 126 127 this.lastHistogram = newHisto; 128 129 return dist; 130 } 131 }