C++ opencv 图片截取不规则ROI区域并将其他区域透明化

目的

将图片内不规则的ROI区域截取下来后,将非ROI区域的像素删除.

主要函数

cvFloodFill()
cvOr()(注: 与cvAnd用法雷同)

代码实现

  IplImage *ipl_img = cvLoadImage("7890.jpg");
  // 将ROI区域用cvLine包裹
  cvLine(ipl_img, cvPoint(50, 100), cvPoint(70, 150), CV_RGB(255,255,255), 2, 8, 1);
  cvLine(ipl_img, cvPoint(70, 150), cvPoint(70, 360), CV_RGB(255,255,255), 2, 8, 1);
  cvLine(ipl_img, cvPoint(70, 360), cvPoint(50, 360), CV_RGB(255,255,255), 2, 8, 1);
  cvLine(ipl_img, cvPoint(50, 360), cvPoint(50, 100), CV_RGB(255,255,255), 2, 8, 1);

  // 掩码层,全黑图片
  Mat image0 = imread("7890.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
  Mat M_mask = image0.clone();
  IplImage mask_img = M_mask;
  cvZero(&mask_img);
  // 同样包裹,点一样
  cvLine(&mask_img, cvPoint(50, 100), cvPoint(70, 150), CV_RGB(0, 255, 255), 2, 8, 1);
  cvLine(&mask_img, cvPoint(70, 150), cvPoint(70, 360), CV_RGB(0, 255, 255), 2, 8, 1);
  cvLine(&mask_img, cvPoint(70, 360), cvPoint(50, 360), CV_RGB(0, 255, 255), 2, 8, 1);
  cvLine(&mask_img, cvPoint(50, 360), cvPoint(50, 100), CV_RGB(0, 255, 255), 2, 8, 1);

  // 不规则ROI区域标定
  cvFloodFill(
      &mask_img,
      cvPoint(60, 250), // 点在ROI区域内即可
      Scalar(255, 255, 255),
      cvScalar(20, 30, 40, 0),
      cvScalar(20, 30, 40, 0));
  cvOr(ipl_img, &mask_img, ipl_img); // 或处理

  // 白色区域透明化
  Mat dst = cv::cvarrToMat(ipl_img); // IplImage* -> Mat
  Mat input_bgra;
  cvtColor(dst, input_bgra, CV_BGR2BGRA);

  // find all while pixel and set alpha value to zero
  for (int y = 0; y < input_bgra.rows; ++y)
  {
    for (int x = 0; x < input_bgra.cols; ++x)
    {
      Vec4b &pixel = input_bgra.at(y, x);
      if (pixel[0] == 255 && pixel[1] == 255 && pixel[2] == 255)
      {
        pixel[3] = 0;
      }
    }
  }
  imwrite("testPng.png", input_bgra); // 注: 一定要以PNG形式保存

备注

图片保存要以PNG格式保存,因为JPG不支持透明背景.

你可能感兴趣的:(C++,opencv,c++)