Ticket #10793: scenechangedetector.patch
| File scenechangedetector.patch, 7.7 KB (added by , 13 years ago) |
|---|
-
mythtv/programs/mythcommflag/ClassicCommDetector.cpp
diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.cpp b/mythtv/programs/mythcommflag/ClassicCommDetector.cpp index 800e83d..bb83323 100644
a b void ClassicCommDetector::Init() 245 222 decoderFoundAspectChanges = false; 246 223 247 224 lastSentCommBreakMap.clear(); 248 225 249 226 // Check if close to 4:3 250 227 if (fabs(((width*1.0)/height) - 1.333333) < 0.1) 251 228 currentAspect = COMM_ASPECT_NORMAL; 252 229 253 230 sceneChangeDetector = new ClassicSceneChangeDetector(width, height, 254 commDetectBorder, horizSpacing, vertSpacing);231 commDetectBorder, fps); 255 232 connect( 256 233 sceneChangeDetector, 257 234 SIGNAL(haveNewInformation(unsigned int,bool,float)), -
mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp
diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp index c449353..ff096a5 100644
a b using namespace std; 6 6 7 7 ClassicSceneChangeDetector::ClassicSceneChangeDetector(unsigned int width, 8 8 unsigned int height, unsigned int commdetectborder_in, 9 unsigned int xspacing_in, unsigned int yspacing_in):9 unsigned int fps_in): 10 10 SceneChangeDetectorBase(width,height), 11 frameNumber(0), 12 previousFrameWasSceneChange(false), 13 xspacing(xspacing_in), 14 yspacing(yspacing_in), 15 commdetectborder(commdetectborder_in) 11 commdetectborder(commdetectborder_in), 12 fps(fps_in), 13 prevSceneEnd(0), 14 thisSceneStart(0) 16 15 { 17 16 histogram = new Histogram; 18 17 previousHistogram = new Histogram; 18 previousSceneHistogram = new Histogram; 19 19 } 20 20 21 21 void ClassicSceneChangeDetector::deleteLater(void) 22 22 { 23 23 delete histogram; 24 24 delete previousHistogram; 25 delete previousSceneHistogram; 25 26 SceneChangeDetectorBase::deleteLater(); 26 27 } 27 28 28 void ClassicSceneChangeDetector::processFrame(unsigned char* frame)29 void ClassicSceneChangeDetector::processFrame(unsigned int frameNumber, unsigned char* frame) 29 30 { 30 31 histogram->generateFromImage(frame, width, height, commdetectborder, 31 32 width-commdetectborder, commdetectborder, 32 height-commdetectborder, xspacing, yspacing);33 height-commdetectborder, 1, 1); 33 34 float similar = histogram->calculateSimilarityWith(*previousHistogram); 34 35 35 bool isSceneChange = (similar < .85 && !previousFrameWasSceneChange); 36 37 emit(haveNewInformation(frameNumber,isSceneChange,similar)); 38 previousFrameWasSceneChange = isSceneChange; 39 40 std::swap(histogram,previousHistogram); 41 frameNumber++; 36 bool isSceneChange = similar < .85; 37 if (isSceneChange) 38 { 39 // If the last scene was recent we can consider it 40 if (frameNumber - prevSceneEnd <= fps * 30) 41 { 42 float prevSim = histogram->calculateSimilarityWith(*previousSceneHistogram); 43 if (prevSim >= 0.85) 44 { 45 // If this scene looks the same as the previous scene then there was no change 46 isSceneChange = false; 47 48 // Undo what we previously said was a scene change 49 emit(haveNewInformation(prevSceneEnd, false, 1.25)); 50 } 51 } 52 53 if (frameNumber - thisSceneStart <= fps / 8) 54 { 55 // Supress change flags on rapidly changing scenery 56 isSceneChange = false; 57 } 58 else 59 { 60 std::swap(previousSceneHistogram, previousHistogram); 61 prevSceneEnd = thisSceneStart; 62 thisSceneStart = frameNumber; 63 } 64 } 65 std::swap(previousHistogram,histogram); 66 67 emit(haveNewInformation(frameNumber, isSceneChange, similar)); 42 68 } 43 69 44 70 /* vim: set expandtab tabstop=4 shiftwidth=4: */ 45 -
mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h
diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h index f4d2200..43a9687 100644
a b class ClassicSceneChangeDetector : public SceneChangeDetectorBase 9 9 { 10 10 public: 11 11 ClassicSceneChangeDetector(unsigned int width, unsigned int height, 12 unsigned int commdetectborder, unsigned int xspacing, 13 unsigned int yspacing); 12 unsigned int commdetectborder, unsigned int fps); 14 13 virtual void deleteLater(void); 15 14 16 void processFrame(unsigned char* frame);15 void processFrame(unsigned int frameNumber, unsigned char* frame); 17 16 18 17 private: 19 18 ~ClassicSceneChangeDetector() {} … … class ClassicSceneChangeDetector : public SceneChangeDetectorBase 21 20 private: 22 21 Histogram* histogram; 23 22 Histogram* previousHistogram; 24 unsigned int frameNumber; 25 bool previousFrameWasSceneChange; 26 unsigned int xspacing, yspacing; 23 Histogram* previousSceneHistogram; 27 24 unsigned int commdetectborder; 25 unsigned int fps; 26 unsigned int prevSceneEnd, thisSceneStart; 28 27 }; 29 28 30 29 #endif -
mythtv/programs/mythcommflag/Histogram.cpp
diff --git a/mythtv/programs/mythcommflag/Histogram.cpp b/mythtv/programs/mythcommflag/Histogram.cpp index 12d2a9a..849f23b 100644
a b unsigned int Histogram::getThresholdForPercentageOfPixels(float percentage) 70 70 71 71 float Histogram::calculateSimilarityWith(const Histogram& other) const 72 72 { 73 long similar = 0; 74 75 for(unsigned int i = 0; i < 256; i++) 73 const int proximity = 5; 74 long similarity = 0; 75 76 similarity += std::min(data[0], 77 other.data[0]); 78 similarity += std::min(data[0] + data[1], 79 other.data[0] + other.data[1]); 80 similarity += std::min(data[0] + data[1] + data[2], 81 other.data[0] + other.data[1] + other.data[2]); 82 83 for(unsigned int i = 0; i <= 256 - proximity; i++) 76 84 { 77 if (data[i] < other.data[i]) 78 similar += data[i]; 79 else 80 similar += other.data[i]; 85 unsigned int mine = 0, others = 0; 86 for (int j = 0; j < proximity; ++j) 87 { 88 mine += data[i+j]; 89 others += other.data[i+j]; 90 } 91 similarity += std::min(mine, others); 81 92 } 82 83 //Using c style cast for old gcc compatibility. 84 return static_cast<float>(similar) / static_cast<float>(numberOfSamples); 93 94 similarity += std::min(data[253] + data[254] + data[255], 95 other.data[253] + other.data[254] + other.data[255]); 96 similarity += std::min(data[254] + data[255], 97 other.data[254] + other.data[255]); 98 similarity += std::min(data[255], 99 other.data[255]); 100 101 return similarity / static_cast<float>(numberOfSamples * proximity); 85 102 } 86 103 87 104 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
mythtv/programs/mythcommflag/SceneChangeDetectorBase.h
diff --git a/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h b/mythtv/programs/mythcommflag/SceneChangeDetectorBase.h index 67296d5..338c80a 100644
a b class SceneChangeDetectorBase : public QObject 11 11 SceneChangeDetectorBase(unsigned int w, unsigned int h) : 12 12 width(w), height(h) {} 13 13 14 virtual void processFrame(unsigned char *frame) = 0;14 virtual void processFrame(unsigned int frameNumber, unsigned char *frame) = 0; 15 15 16 16 signals: 17 17 void haveNewInformation(unsigned int framenum, bool scenechange,
