BlueAndBug 2020-10-21 09:00 采纳率: 0%
浏览 77

关于图像分割代码中的初始化和参数更新不是很明白,代码中用的是什么样的初始化方法和参数更新方式,有没有人看一下代码解释一下?

代码如下:
LBMixtureGaussians.cpp:

#include "LBMixtureOfGaussians.h"

using namespace bgslibrary::algorithms;

LBMixtureOfGaussians::LBMixtureOfGaussians() :
  sensitivity(81), bgThreshold(83), learningRate(59), noiseVariance(206)
{
  std::cout << "LBMixtureOfGaussians()" << std::endl;
  setup("./config/LBMixtureOfGaussians.xml");
}

LBMixtureOfGaussians::~LBMixtureOfGaussians()
{
  delete m_pBGModel;
  std::cout << "~LBMixtureOfGaussians()" << std::endl;
}

void LBMixtureOfGaussians::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
{
  init(img_input, img_output, img_bgmodel);

  IplImage *frame = new IplImage(img_input);

  if (firstTime)
  {
    int w = cvGetSize(frame).width;
    int h = cvGetSize(frame).height;

    m_pBGModel = new BGModelMog(w, h);
    m_pBGModel->InitModel(frame);
  }

  m_pBGModel->setBGModelParameter(0, sensitivity);
  m_pBGModel->setBGModelParameter(1, bgThreshold);
  m_pBGModel->setBGModelParameter(2, learningRate);
  m_pBGModel->setBGModelParameter(3, noiseVariance);

  m_pBGModel->UpdateModel(frame);

  img_foreground = cv::cvarrToMat(m_pBGModel->GetFG());
  img_background = cv::cvarrToMat(m_pBGModel->GetBG());

#ifndef MEX_COMPILE_FLAG
  if (showOutput)
  {
    cv::imshow("MOG Mask", img_foreground);
    cv::imshow("MOG Model", img_background);
  }
#endif

  img_foreground.copyTo(img_output);
  img_background.copyTo(img_bgmodel);

  delete frame;

  firstTime = false;
}

void LBMixtureOfGaussians::saveConfig()
{
  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_WRITE);

  cvWriteInt(fs, "sensitivity", sensitivity);
  cvWriteInt(fs, "bgThreshold", bgThreshold);
  cvWriteInt(fs, "learningRate", learningRate);
  cvWriteInt(fs, "noiseVariance", noiseVariance);
  cvWriteInt(fs, "showOutput", showOutput);

  cvReleaseFileStorage(&fs);
}

void LBMixtureOfGaussians::loadConfig()
{
  CvFileStorage* fs = cvOpenFileStorage(config_xml.c_str(), nullptr, CV_STORAGE_READ);

  sensitivity = cvReadIntByName(fs, nullptr, "sensitivity", 81);
  bgThreshold = cvReadIntByName(fs, nullptr, "bgThreshold", 83);
  learningRate = cvReadIntByName(fs, nullptr, "learningRate", 59);
  noiseVariance = cvReadIntByName(fs, nullptr, "noiseVariance", 206);
  showOutput = cvReadIntByName(fs, nullptr, "showOutput", true);

  cvReleaseFileStorage(&fs);
}

BGModelMog.cpp:



#include "BGModelMog.h"

namespace lb_library
{
  namespace MixtureOfGaussians
  {
    BGModelMog::BGModelMog(int width, int height) : BGModel(width, height)
    {
      m_alpha = LEARNINGRATEMOG;
      m_threshold = THRESHOLDMOG*THRESHOLDMOG;
      m_noise = INITIALVARMOG;

      m_T = BGTHRESHOLDMOG;

      m_pMOG = new MOGDATA[NUMBERGAUSSIANS*m_width*m_height];
      m_pK = new int[m_width*m_height];

      MOGDATA *pMOG = m_pMOG;
      int *pK = m_pK;

      for (int i = 0; i < (m_width * m_height); i++)
      {
        for (int k = 0; k < NUMBERGAUSSIANS; k++)
        {
          pMOG->mu.Red = 0.0;
          pMOG->mu.Green = 0.0;
          pMOG->mu.Blue = 0.0;

          pMOG->var.Red = 0.0;
          pMOG->var.Green = 0.0;
          pMOG->var.Blue = 0.0;

          pMOG->w = 0.0;
          pMOG->sortKey = 0.0;

          pMOG++;
        }

        pK[i] = 0;
      }
    }

    BGModelMog::~BGModelMog()
    {
      delete[] m_pMOG;
      delete[] m_pK;
    }

    void BGModelMog::setBGModelParameter(int id, int value)
    {
      double dvalue = (double)value / 255.0;

      switch (id)
      {
      case 0:
        m_threshold = 100.0*dvalue*dvalue;
        break;

      case 1:
        m_T = dvalue;
        break;

      case 2:
        m_alpha = dvalue*dvalue*dvalue;
        break;

      case 3:
        m_noise = 100.0*dvalue;;
        break;
      }

      return;
    }

    void BGModelMog::Init()
    {
      MOGDATA *pMOG = m_pMOG;
      int *pK = m_pK;

      Image<BYTERGB> prgbSrc(m_SrcImage);

      int n = 0;
      for (int i = 0; i < m_height; i++)
      {
        for (int j = 0; j < m_width; j++)
        {
          pMOG[0].mu.Red = prgbSrc[i][j].Red;
          pMOG[0].mu.Green = prgbSrc[i][j].Green;
          pMOG[0].mu.Blue = prgbSrc[i][j].Blue;

          pMOG[0].var.Red = m_noise;
          pMOG[0].var.Green = m_noise;
          pMOG[0].var.Blue = m_noise;

          pMOG[0].w = 1.0;
          pMOG[0].sortKey = pMOG[0].w / sqrt(pMOG[0].var.Red + pMOG[0].var.Green + pMOG[0].var.Blue);

          pK[n] = 1;
          n++;

          pMOG += NUMBERGAUSSIANS;
        }
      }

      return;
    }

    void BGModelMog::Update()
    {
      int kBG;

      MOGDATA *pMOG = m_pMOG;
      int *pK = m_pK;

      Image<BYTERGB> prgbSrc(m_SrcImage);
      Image<BYTERGB> prgbBG(m_BGImage);
      Image<BYTERGB> prgbFG(m_FGImage);

      int n = 0;
      for (int i = 0; i < m_height; i++)
      {
        for (int j = 0; j < m_width; j++)
        {
          double srcR = (double)prgbSrc[i][j].Red;
          double srcG = (double)prgbSrc[i][j].Green;
          double srcB = (double)prgbSrc[i][j].Blue;

          // Find matching distribution

          int kHit = -1;

          for (int k = 0; k < pK[n]; k++)
          {
            // Mahalanobis distance
            double dr = srcR - pMOG[k].mu.Red;
            double dg = srcG - pMOG[k].mu.Green;
            double db = srcB - pMOG[k].mu.Blue;
            double d2 = dr*dr / pMOG[k].var.Red + dg*dg / pMOG[k].var.Green + db*db / pMOG[k].var.Blue;

            if (d2 < m_threshold)
            {
              kHit = k;
              break;
            }
          }

          // Adjust parameters

          // matching distribution found
          if (kHit != -1)
          {
            for (int k = 0; k < pK[n]; k++)
            {
              if (k == kHit)
              {
                pMOG[k].w = pMOG[k].w + m_alpha*(1.0f - pMOG[k].w);

                double d;

                d = srcR - pMOG[k].mu.Red;
                if (d*d > DBL_MIN)
                  pMOG[k].mu.Red += m_alpha*d;

                d = srcG - pMOG[k].mu.Green;
                if (d*d > DBL_MIN)
                  pMOG[k].mu.Green += m_alpha*d;

                d = srcB - pMOG[k].mu.Blue;
                if (d*d > DBL_MIN)
                  pMOG[k].mu.Blue += m_alpha*d;

                d = (srcR - pMOG[k].mu.Red)*(srcR - pMOG[k].mu.Red) - pMOG[k].var.Red;
                if (d*d > DBL_MIN)
                  pMOG[k].var.Red += m_alpha*d;

                d = (srcG - pMOG[k].mu.Green)*(srcG - pMOG[k].mu.Green) - pMOG[k].var.Green;
                if (d*d > DBL_MIN)
                  pMOG[k].var.Green += m_alpha*d;

                d = (srcB - pMOG[k].mu.Blue)*(srcB - pMOG[k].mu.Blue) - pMOG[k].var.Blue;
                if (d*d > DBL_MIN)
                  pMOG[k].var.Blue += m_alpha*d;

                pMOG[k].var.Red = (std::max)(pMOG[k].var.Red, m_noise);
                pMOG[k].var.Green = (std::max)(pMOG[k].var.Green, m_noise);
                pMOG[k].var.Blue = (std::max)(pMOG[k].var.Blue, m_noise);
              }
              else
                pMOG[k].w = (1.0 - m_alpha)*pMOG[k].w;
            }
          }
          // no match found... create new one
          else
          {
            if (pK[n] < NUMBERGAUSSIANS)
              pK[n]++;

            kHit = pK[n] - 1;

            if (pK[n] == 1)
              pMOG[kHit].w = 1.0;
            else
              pMOG[kHit].w = LEARNINGRATEMOG;

            pMOG[kHit].mu.Red = srcR;
            pMOG[kHit].mu.Green = srcG;
            pMOG[kHit].mu.Blue = srcB;

            pMOG[kHit].var.Red = m_noise;
            pMOG[kHit].var.Green = m_noise;
            pMOG[kHit].var.Blue = m_noise;
          }

          // Normalize weights

          double wsum = 0.0;

          for (int k = 0; k < pK[n]; k++)
            wsum += pMOG[k].w;

          double wfactor = 1.0 / wsum;

          for (int k = 0; k < pK[n]; k++)
          {
            pMOG[k].w *= wfactor;
            pMOG[k].sortKey = pMOG[k].w / sqrt(pMOG[k].var.Red + pMOG[k].var.Green + pMOG[k].var.Blue);
          }

          // Sort distributions

          for (int k = 0; k < kHit; k++)
          {
            if (pMOG[kHit].sortKey > pMOG[k].sortKey)
            {
              std::swap(pMOG[kHit], pMOG[k]);
              break;
            }
          }

          // Determine background distributions

          wsum = 0.0;

          for (int k = 0; k < pK[n]; k++)
          {
            wsum += pMOG[k].w;

            if (wsum > m_T)
            {
              kBG = k;
              break;
            }
          }

          if (kHit > kBG)
            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 255;
          else
            prgbFG[i][j].Red = prgbFG[i][j].Green = prgbFG[i][j].Blue = 0;

          prgbBG[i][j].Red = (unsigned char)pMOG[0].mu.Red;
          prgbBG[i][j].Green = (unsigned char)pMOG[0].mu.Green;
          prgbBG[i][j].Blue = (unsigned char)pMOG[0].mu.Blue;

          pMOG += NUMBERGAUSSIANS;

          n++;
        }
      }

      return;
    }
  }
}

  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-07-25 01:50
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    这段代码是用于实现基于混合高斯模型的背景抽取算法(LBM)。以下是对代码的一些解释和分析:

    初始化和参数更新部分

    • 初始化: setup 函数用来加载配置文件并设置一些基本参数。这包括敏感度、阈值、学习率和噪声方差。
    • 参数更新:
      • update 函数负责根据输入图像计算前景和背景掩码,并将结果保存到输出图像中。

    背景抽取部分

    • 计算背景掩码:update 函数内部,首先通过 MOG 模型对输入图像进行处理,然后计算出前景和背景掩码。
      • 获取前景掩码 (img_foreground) 和背景掩码 (img_background)。
      • 如果设置了显示输出,则在控制台展示前景和背景掩码。

    结果保存与恢复部分

    • 保存配置: saveConfig 函数用于保存当前配置信息。
    • 读取配置: loadConfig 函数用于从配置文件中读取参数。

    总结来说,这段代码主要涉及图像预处理、混合高斯模型训练以及前景和背景掩码生成的过程。通过设置合适的参数,可以优化模型性能以达到更佳的效果。

    评论

报告相同问题?

悬赏问题

  • ¥15 FileNotFoundError 解决方案
  • ¥15 uniapp实现如下图的图表功能
  • ¥15 u-subsection如何修改相邻两个节点样式
  • ¥30 vs2010开发 WFP(windows filtering platform)
  • ¥15 服务端控制goose报文控制块的发布问题
  • ¥15 学习指导与未来导向啊
  • ¥15 求多普勒频移瞬时表达式
  • ¥15 如果要做一个老年人平板有哪些需求
  • ¥15 k8s生产配置推荐配置及部署方案
  • ¥15 matlab提取运动物体的坐标