Ticket #10793: scene-change-detector.diff

File scene-change-detector.diff, 8.1 KB (added by bryan@…, 6 years ago)

Updated Scene Change Detector (uses averaging to make the detection more reliable)

  • mythtv/programs/mythcommflag/ClassicCommDetector.cpp

    diff --git a/mythtv/programs/mythcommflag/ClassicCommDetector.cpp b/mythtv/programs/mythcommflag/ClassicCommDetector.cpp
    index 800e83d..327548f 100644
    a b ClassicCommDetector::ClassicCommDetector(SkipType commDetectMethod_in, 
    152152    preRoll(0),                                postRoll(0)
    153153{
    154154    commDetectBorder =
    155         gCoreContext->GetNumSetting("CommDetectBorder", 20);
     155        gCoreContext->GetNumSetting("CommDetectBorder", 5);
    156156    commDetectBlankFrameMaxDiff =
    157157        gCoreContext->GetNumSetting("CommDetectBlankFrameMaxDiff", 25);
    158158    commDetectDarkBrightness =
    void ClassicCommDetector::Init() 
    206206            .arg(width).arg(height)
    207207            .arg(player->GetFrameRate()).arg(commDetectMethod));
    208208
    209     if ((width * height) > 1000000)
     209    /*if ((width * height) > 1000000)
    210210    {
    211211        horizSpacing = 10;
    212212        vertSpacing = 10;
    void ClassicCommDetector::Init() 
    230230    {
    231231        horizSpacing = 4;
    232232        vertSpacing = 4;
    233     }
     233    }*/
    234234
     235    horizSpacing = 1;
     236    vertSpacing = 1;
     237   
    235238    LOG(VB_COMMFLAG, LOG_INFO,
    236239        QString("Using Sample Spacing of %1 horizontal & %2 vertical pixels.")
    237240            .arg(horizSpacing).arg(vertSpacing));
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    790793        {
    791794            fInfo.aspect = frameInfo[lastFrameNumber].aspect;
    792795            fInfo.format = frameInfo[lastFrameNumber].format;
     796            fInfo.flagMask = COMM_FRAME_SKIPPED;
     797            while (++lastFrameNumber < curFrameNumber)
     798            {
     799                // Only overwrite if there was no info for the frame yet
     800                if (!frameInfo.contains(lastFrameNumber))
     801                    frameInfo[lastFrameNumber] = fInfo;
     802            }
    793803        }
    794         fInfo.flagMask = COMM_FRAME_SKIPPED;
    795 
    796         lastFrameNumber++;
    797         while(lastFrameNumber < curFrameNumber)
    798             frameInfo[lastFrameNumber++] = fInfo;
    799 
    800804        fInfo.flagMask = 0;
    801805    }
    802806    lastFrameNumber = curFrameNumber;
    void ClassicCommDetector::ProcessFrame(VideoFrame *frame, 
    808812
    809813    if (commDetectMethod & COMM_DETECT_SCENE)
    810814    {
    811         sceneChangeDetector->processFrame(framePtr);
     815        sceneChangeDetector->processFrame(curFrameNumber, framePtr);
    812816    }
    813817
    814818    stationLogoPresent = false;
    void ClassicCommDetector::BuildAllMethodsCommList(void) 
    13971401                fbp->score += 20;
    13981402            }
    13991403
    1400             if ((fbp->scRate > 1.0) &&
    1401                 (fbp->logoCount < (fbp->frames * .90)))
     1404            if ((fbp->scRate > 0.75) &&
     1405                (fbp->logoCount < (fbp->frames * .25)))
    14021406            {
    14031407                if (verboseDebugging)
    1404                     LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 1.0, -10");
     1408                    LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 0.75, -10");
    14051409                fbp->score -= 10;
    14061410
    1407                 if (fbp->scRate > 2.0)
     1411                if (fbp->scRate > 1.5)
    14081412                {
    14091413                    if (verboseDebugging)
    1410                         LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 2.0, -10");
     1414                        LOG(VB_COMMFLAG, LOG_DEBUG, "      scRate > 1.5, -10");
    14111415                    fbp->score -= 10;
    14121416                }
    14131417            }
  • mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp

    diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.cpp
    index c449353..ea93b1b 100644
    a b ClassicSceneChangeDetector::ClassicSceneChangeDetector(unsigned int width, 
    88        unsigned int height, unsigned int commdetectborder_in,
    99        unsigned int xspacing_in, unsigned int yspacing_in):
    1010    SceneChangeDetectorBase(width,height),
    11     frameNumber(0),
    1211    previousFrameWasSceneChange(false),
    1312    xspacing(xspacing_in),
    1413    yspacing(yspacing_in),
    void ClassicSceneChangeDetector::deleteLater(void) 
    2524    SceneChangeDetectorBase::deleteLater();
    2625}
    2726
    28 void ClassicSceneChangeDetector::processFrame(unsigned char* frame)
     27void ClassicSceneChangeDetector::processFrame(unsigned int frameNumber, unsigned char* frame)
    2928{
    3029    histogram->generateFromImage(frame, width, height, commdetectborder,
    3130                                 width-commdetectborder, commdetectborder,
    void ClassicSceneChangeDetector::processFrame(unsigned char* frame) 
    3837    previousFrameWasSceneChange = isSceneChange;
    3938
    4039    std::swap(histogram,previousHistogram);
    41     frameNumber++;
    4240}
    4341
    4442/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h

    diff --git a/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h b/mythtv/programs/mythcommflag/ClassicSceneChangeDetector.h
    index f4d2200..6b4060d 100644
    a b class ClassicSceneChangeDetector : public SceneChangeDetectorBase 
    1313        unsigned int yspacing);
    1414    virtual void deleteLater(void);
    1515
    16     void processFrame(unsigned char* frame);
     16    void processFrame(unsigned int frameNumber, unsigned char* frame);
    1717
    1818  private:
    1919    ~ClassicSceneChangeDetector() {}
    class ClassicSceneChangeDetector : public SceneChangeDetectorBase 
    2121  private:
    2222    Histogram* histogram;
    2323    Histogram* previousHistogram;
    24     unsigned int frameNumber;
    2524    bool previousFrameWasSceneChange;
    2625    unsigned int xspacing, yspacing;
    2726    unsigned int commdetectborder;
  • 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,