Ticket #10793: scenechangedetector.patch

File scenechangedetector.patch, 7.7 KB (added by bryan@…, 7 years ago)

SceneChange? and Histogram changes

  • 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() 
    245222    decoderFoundAspectChanges = false;
    246223
    247224    lastSentCommBreakMap.clear();
    248225
    249226    // Check if close to 4:3
    250227    if (fabs(((width*1.0)/height) - 1.333333) < 0.1)
    251228        currentAspect = COMM_ASPECT_NORMAL;
    252229
    253230    sceneChangeDetector = new ClassicSceneChangeDetector(width, height,
    254         commDetectBorder, horizSpacing, vertSpacing);
     231        commDetectBorder, fps);
    255232    connect(
    256233         sceneChangeDetector,
    257234         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; 
    66
    77ClassicSceneChangeDetector::ClassicSceneChangeDetector(unsigned int width,
    88        unsigned int height, unsigned int commdetectborder_in,
    9         unsigned int xspacing_in, unsigned int yspacing_in):
     9        unsigned int fps_in):
    1010    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)
    1615{
    1716    histogram = new Histogram;
    1817    previousHistogram = new Histogram;
     18    previousSceneHistogram = new Histogram;
    1919}
    2020
    2121void ClassicSceneChangeDetector::deleteLater(void)
    2222{
    2323    delete histogram;
    2424    delete previousHistogram;
     25    delete previousSceneHistogram;
    2526    SceneChangeDetectorBase::deleteLater();
    2627}
    2728
    28 void ClassicSceneChangeDetector::processFrame(unsigned char* frame)
     29void ClassicSceneChangeDetector::processFrame(unsigned int frameNumber, unsigned char* frame)
    2930{
    3031    histogram->generateFromImage(frame, width, height, commdetectborder,
    3132                                 width-commdetectborder, commdetectborder,
    32                                  height-commdetectborder, xspacing, yspacing);
     33                                 height-commdetectborder, 1, 1);
    3334    float similar = histogram->calculateSimilarityWith(*previousHistogram);
    3435
    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));
    4268}
    4369
    4470/* 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 
    99{
    1010  public:
    1111    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);
    1413    virtual void deleteLater(void);
    1514
    16     void processFrame(unsigned char* frame);
     15    void processFrame(unsigned int frameNumber, unsigned char* frame);
    1716
    1817  private:
    1918    ~ClassicSceneChangeDetector() {}
    class ClassicSceneChangeDetector : public SceneChangeDetectorBase 
    2120  private:
    2221    Histogram* histogram;
    2322    Histogram* previousHistogram;
    24     unsigned int frameNumber;
    25     bool previousFrameWasSceneChange;
    26     unsigned int xspacing, yspacing;
     23    Histogram* previousSceneHistogram;
    2724    unsigned int commdetectborder;
     25    unsigned int fps;
     26    unsigned int prevSceneEnd, thisSceneStart;
    2827};
    2928
    3029#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) 
    7070
    7171float Histogram::calculateSimilarityWith(const Histogram& other) const
    7272{
    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++)
    7684    {
    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);
    8192    }
    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);
    85102}
    86103
    87104/* 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 
    1111    SceneChangeDetectorBase(unsigned int w, unsigned int h) :
    1212        width(w), height(h) {}
    1313
    14     virtual void processFrame(unsigned char *frame) = 0;
     14    virtual void processFrame(unsigned int frameNumber, unsigned char *frame) = 0;
    1515
    1616  signals:
    1717    void haveNewInformation(unsigned int framenum, bool scenechange,