zoukankan      html  css  js  c++  java
  • opencv3更换图片背景

    #include <opencv2/opencv.hpp>
    #include <iostream>

    using namespace std;
    using namespace cv;

    void ChangeImgBG();
    Mat HandleImgData(Mat &img);
    /*
    图片背景替换
    知识点:分水岭分割、高斯模糊
    处理步骤:数据组装-KMeans分割-背景消除-生成遮罩-模糊-输出
    */
    void ChangeImgBG()
    {
      char* win1 = "window1";
      char* win2 = "window2";
      char* win3 = "window3";
      char* win4 = "window4";
      char* win5 = "window5";
      char* win6 = "window6";
      namedWindow(win1,CV_WINDOW_AUTOSIZE);//创建窗口 win1
      namedWindow(win2,CV_WINDOW_AUTOSIZE);//创建窗口 win2
      namedWindow(win3,CV_WINDOW_AUTOSIZE);//创建窗口 win3
      namedWindow(win4, CV_WINDOW_AUTOSIZE);//创建窗口 win4
      namedWindow(win5, CV_WINDOW_AUTOSIZE);//创建窗口 win5
      namedWindow(win6, CV_WINDOW_AUTOSIZE);//创建窗口 win6

      Mat img1, img2;
      //加载图片
      img1 = imread("D:\参考手册\opencv素材\xl.jpg");
      if (img1.empty())
      {
        cout << "image not found..." << endl;
        exit(0);//如果图片不存在,退出程序
      }
      img2 = img1.clone();
      //显示原始图片
      imshow(win1,img1);
      //组装数据
      Mat points = HandleImgData(img1);

      //Kmeans处理
      int numCluster = 4;
      Mat labels;
      Mat centers;
      TermCriteria termCriteria = TermCriteria(TermCriteria::EPS + TermCriteria::COUNT,10,0.1);

      kmeans(points, numCluster,labels, termCriteria,3,KMEANS_PP_CENTERS,centers);
      //遮罩
      Mat mask = Mat::zeros(img1.size(),CV_8UC1);
      int index = img1.rows*2 + 2;
      int cindex = labels.at<int>(index,0);//背景设置为0
      int height = img1.rows;
      int width = img1.cols;

      for (int row = 0;row<height;row++)
      {
        for (int col =0;col<width;col++)
        {
          index = row*width + col;
          int label = labels.at<int>(index,0);
          if (label ==cindex)
          {
            img2.at<Vec3b>(row, col)[0] = 0;
            img2.at<Vec3b>(row, col)[1] = 0;
            img2.at<Vec3b>(row, col)[2] = 0;
            mask.at<uchar>(row, col) = 0;
          }
          else
          {
            mask.at<uchar>(row, col) = 255;
          }
        }
      }

      //腐蚀
      Mat k = getStructuringElement(MORPH_RECT,Size(3,3),Point(-1,-1));
      erode(mask,mask,k);
      imshow(win4,mask);

      //高斯模糊
      GaussianBlur(mask,mask,Size(3,3),0,0);
      imshow(win5,mask);

      //通道混合
      RNG rng(12345);
      Vec3b color;
      color[0] = rng.uniform(0,255);
      color[1] = rng.uniform(0, 255);
      color[2] = rng.uniform(0, 255);
      Mat result(img1.size(),img1.type());

      double d1 = 0.0;
      int r = 0, g = 0, b = 0;
      int r1 = 0, g1 = 0, b1 = 0;
      int r2 = 0, g2 = 0, b2 = 0;


      for (int row = 0; row < height;row++)
      {
        for (int col=0;col<width;col++)
        {
          int m = mask.at<uchar>(row,col);
          if (m==255)
          {
            result.at<Vec3b>(row, col) = img1.at<Vec3b>(row,col);//前景
          }
          else if (m == 0)
          {
            result.at<Vec3b>(row, col) = color;//背景
          }
          else
          {
            d1 = m / 255.0;
            b1 = img1.at<Vec3b>(row, col)[0];
            g1 = img1.at<Vec3b>(row, col)[1];
            r1 = img1.at<Vec3b>(row, col)[2];

            b2 = color[0];
            g2 = color[1];
            r2 = color[2];

            b = b1*d1 + b2*(1.0-d1);
            g = g1*d1 + g2*(1.0-d1);
            r = r1*d1 + r2*(1.0-d1);

            result.at<Vec3b>(row,col)[0] = b;
            result.at<Vec3b>(row, col)[1] = g;
            result.at<Vec3b>(row, col)[2] = r;
          }
        }
      }

      //输出
      imshow(win2,mask);
      imshow(win3,img2);
      imshow(win6,result);
      //保存处理后的图片
      imwrite("result-2.jpg",result);
    }

    //组装样本数据
    Mat HandleImgData(Mat &img)
    {
      int width = img.cols;
      int height = img.rows;
      int count1 = width*height;
      int channels1 = img.channels();

      Mat points(count1, channels1,CV_32F,Scalar(10));
      int index = 0;
      for (int row = 0; row < height;row++)
      {
        for (int col = 0; col < width;col++)
        {
          index = row*width + col;
          Vec3b bgr = img.at<Vec3b>(row,col);
          points.at<float>(index, 0) = static_cast<int>(bgr[0]);
          points.at<float>(index, 1) = static_cast<int>(bgr[1]);
          points.at<float>(index, 2) = static_cast<int>(bgr[2]);
        }
      }
      return points;
    }

    int main()
    {
      ChangeImgBG();

      waitKey(0);
      return 0;
    }

    运行效果:

     

  • 相关阅读:
    浅谈计算机速度变慢
    日志中的秘密:Windows登录类型知多少?ZT
    在应用程序代码中使用 FOR XML 结果 [From MS]
    Two sql tips
    Web Service Error: “The request failed with HTTP status 401: Unauthorized.”ZT
    [转载]大话MVP
    WCF服务编程 学习笔记(1)
    [转]ExtJS的使用方法汇总—配置和表格控件使用
    [转载]谈谈关于MVP模式中VP交互问题
    [转载]SCSF 系列:Smart Client Software Factory 中 MVP 模式最佳实践
  • 原文地址:https://www.cnblogs.com/herd/p/9205579.html
Copyright © 2011-2022 走看看