OpenCV4(16)-图像ROI与ROI操作(C++,Python,JS)

目录

环境

知识点

C++代码

JS代码

结果展示

返回总目录


环境

  • Python:3.6.5 OpenCV 4.1.2
  • C++:OpenCV 4.1.2
  • JS:OpenCV 4.5.0

环境搭建可参考:B站视频

欢迎访问博主搭建的 在线运行平台 (o゜▽゜)o☆

知识点

ROI解释:

图像的 ROI(region of interest) 是指图像中感兴趣区域、在 OpenCV 中图像设置图像 ROI 区域,实现只对 ROI 区域的操作。

提取不规则ROI区域的一般步骤:

1、通过inRange函数生成mask

2、通过与操作提取ROI

C++代码

#ifndef DAY16
#define DAY16

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

using namespace std;
using namespace cv;

void day16() {

	Mat src = imread("G://opencvTest//scene.jpg");
	namedWindow("input", WINDOW_AUTOSIZE);
	imshow("input", src);
	int h = src.rows;
	int w = src.cols;

	// 获取ROI
	int cy = h / 2;
	int cx = w / 2;
	Rect rect(cx - 100, cy - 100, 200, 200);
	Mat roi = src(rect);
	imshow("roi", roi);

	Mat image = roi.clone();
	// 直接更改ROI,因为是直接赋值的,指向同一块内存区域,所以原图也会被修改
	roi.setTo(Scalar(255, 0, 0));
	imshow("result", src);

	// 更改拷贝的ROI,指向不同的内存区域,所以原图不受影响
	image.setTo(Scalar(0, 0, 255));
	imshow("result2", src);
	imshow("copy roi", image);

	// 获取不规则形状的ROI,通过inRange函数
	Mat src2 = imread("G://opencvTest//tinygreen.jpg");
	imshow("src2", src2);
	Mat hsv, mask;
	cvtColor(src2, hsv, COLOR_BGR2HSV);
	inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);
	imshow("mask", mask);

	// 通过mask提取人物部分,即我们的ROI。mask的白色区域才会执行与操作,黑色区域不执行
	Mat person;
	bitwise_not(mask, mask);
	bitwise_and(src2, src2, person, mask);
	imshow("person", person);

	// 生成一张蓝色背景
	Mat result = Mat::zeros(src2.size(), src2.type());
	result.setTo(Scalar(255, 0, 0));

	// 将蓝色背景与ROI融合
	Mat dst;
	bitwise_not(mask, mask);
	bitwise_or(result, result, dst, mask);
	add(dst, person, dst);

	imshow("dst", dst);

	waitKey();
}

#endif // !DAY16

JS代码

onOpenCvReady() {

  // 官方文档链接:https://docs.opencv.org/4.5.0/de/d06/tutorial_js_basic_ops.html
  // 官方文档链接:https://docs.opencv.org/4.5.0/db/d64/tutorial_js_colorspaces.html
  const cv = window.cv

  const src = this.createMat(cv, 'source', { name: 'imageSrcRaw' })

  // 转化到 HSV 色彩空间
  const hsv = this.createMat(cv, 'empty')
  cv.cvtColor(src, hsv, cv.COLOR_RGB2HSV)

  // 获取背景蒙版,即绿幕部分为白,前景人物部分为黑
  const mask = this.createMat(cv, 'empty')
  const low = this.createMat(cv, 'options', {
    rows: src.rows,
    cols: src.cols,
    type: cv.CV_8UC3,
    initValue: [35, 43, 46, 255]
  })
  const high = this.createMat(cv, 'options', {
    rows: src.rows,
    cols: src.cols,
    type: cv.CV_8UC3,
    initValue: [77, 255, 255, 255]
  })
  cv.inRange(hsv, low, high, mask)

  // 蒙版取非,即前景人物部分为白色
  const mask_not = this.createMat(cv, 'empty')
  cv.bitwise_not(mask, mask_not)

  // 利用蒙版,将人物部分抠出
  const people = this.createMat(cv, 'empty')
  cv.bitwise_and(src, src, people, mask_not)

  // 取一张背景图,并截取与mask相同尺寸的部分
  const scene = this.createMat(cv, 'source', { name: 'imageSrcRaw2' })
  if (scene.cols < people.cols || scene.rows < people.rows) {
    this.$message.error('背景图的尺寸必须大于等于输入图像的尺寸')
    // 销毁所有 mat
    this.destoryAllMats()
    return
  }
  const rect = new cv.Rect(0, 0, people.cols, people.rows)
  let dstScene = this.createMat(cv, 'empty')
  dstScene = scene.roi(rect)

  // 利用蒙版,在背景图中扣掉待填充的人物蒙版部分
  const sceneBackground = this.createMat(cv, 'empty')
  cv.bitwise_and(dstScene, dstScene, sceneBackground, mask)

  // 或操作,将人物融入背景图中
  const finalImage = this.createMat(cv, 'empty')
  cv.bitwise_or(sceneBackground, people, finalImage)

  // 显示图像
  cv.imshow('canvasOutput', finalImage)

  // 销毁所有 mat
  this.destoryAllMats()
},
createMat(cv, type, ops) {
  switch (type) {
    case 'source':
      if (ops && ops.name) {
        const mat = cv.imread(ops.name)
        this.mats.push(mat)
        return mat
      }
      break
    case 'empty': {
      const mat = new cv.Mat()
      this.mats.push(mat)
      return mat
    }
    case 'options':
      if (ops && ops.rows && ops.cols && ops.type && ops.initValue) {
        const mat = new cv.Mat(ops.rows, ops.cols, ops.type, ops.initValue)
        this.mats.push(mat)
        return mat
      }
      break
    default:
      break
  }
},
destoryAllMats() {
  let i = 0
  this.mats.forEach(item => {
    item.delete()
    i++
  })
  this.mats = []
  console.log('销毁图象数:', i)
}

结果展示

result

返回总目录

OpenCV4学习笔记 - 目录

如果这篇文章对您有帮助,欢迎给我的 github项目 点一个⭐ ο(=•ω<=)ρ⌒☆

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Apple_Coco

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值