OpenCV4(9)-色彩空间的转换及应用(C++,Python,JS)

本文围绕OpenCV4展开,介绍了Python、C++、JS三种语言的开发环境,包括对应版本。阐述了RGB、HSV等色彩空间知识点,以及色彩空间转换、提取指定色彩范围区域等API。还给出不同颜色在HSV空间取值范围示例,可用于人物与绿幕背景分离等应用。

目录

环境

知识点

C++代码

Python代码

JS代码

结果展示

返回总目录


环境

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

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

知识点

- RGB色彩空间

是我们最常用的色彩空间,且与设备无关。

- HSV色彩空间

对于一些直方图相关的图像处理和算法,将其转到HSV色彩空间,通常会取得较好的效果。

- YUV色彩空间

一种跟设备有关的色彩空间。

- YCrCb色彩空间

常用作皮肤检测,根据一些颜色的统计模型,通常会取得较好的效果。

API知识点

- 色彩空间转换 cvtColor

- 提取指定色彩范围区域 inRange

注:关于 HSV 各通道在 OpenCV 中取值范围的确定

上图清晰的列出来不同的颜色在HSV色彩空间的最小值和最大值。利用这个取值范围,我们便可以实现一些好玩的应用。

例如,绿色在HSV色彩空间的取值范围是(35, 43, 46)—(77, 255, 255)。通过inRange函数,可以很方便的将人物和绿幕背景分离出来。再通过像素的逻辑操作与或非,便可以实现更换背景的效果~~

C++代码

#ifndef DAY09
#define DAY09

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

using namespace std;
using namespace cv;

void day09() {

	Mat src = imread("E:\\_Image\\OpenCVTest\\tinygreen.jpg");
	if (src.empty()) {
		cout << "could not load image.." << endl;
		return;
	}
	imshow("src", src);

	Mat hsv, mask, mask_not, people;
	cvtColor(src, hsv, COLOR_BGR2HSV);

	// 获取背景蒙版,即绿幕部分为白,前景人物部分为黑
	inRange(hsv, Scalar(35, 43, 46), Scalar(77, 255, 255), mask);
	imshow("mask", mask);
	// 蒙版取非,即前景人物部分为白色
	bitwise_not(mask, mask_not);
	imshow("mask_not", mask_not);

	// 利用蒙版,将人物部分抠出
	bitwise_and(src, src, people, mask_not);
	imshow("people", people);

	// 取一张背景图,并截取与mask相同尺寸的部分
	Mat scene = imread("E:\\_Image\\OpenCVTest\\scene.jpg");
	Mat dstScene(scene, Rect(0, 0, people.cols, people.rows));
	imshow("dstScene", dstScene);

	// 利用蒙版,在背景图中扣掉待填充的人物蒙版部分
	Mat sceneBackground, finalImage;
	bitwise_and(dstScene, dstScene, sceneBackground, mask);
	imshow("sceneBackground", sceneBackground);

	// 或操作,将人物融入背景图中
	bitwise_or(sceneBackground, people, finalImage);
	imshow("final", finalImage);

	waitKey(0);
}

#endif // !DAY09

Python代码

import cv2 as cv

# 查看版本
print(cv.__version__)

# 读取显示图像
src = cv.imread("E:/_Image/OpenCVTest/tinygreen.jpg")
cv.imshow("bgr", src)

# RGB to HSV
hsv = cv.cvtColor(src, cv.COLOR_BGR2HSV)
cv.imshow("hsv", hsv)

# RGB to YUV
yuv = cv.cvtColor(src, cv.COLOR_BGR2YUV)
cv.imshow("yuv", yuv)

# RGB to YUV
ycrcb = cv.cvtColor(src, cv.COLOR_BGR2YCrCb)
cv.imshow("ycrcb", ycrcb)

# 获取背景蒙版,即绿幕部分为白,前景人物部分为黑
mask = cv.inRange(hsv, (35, 43, 46), (77, 255, 255))
cv.imshow("mask", mask)

# 蒙版取非,即前景人物部分为白色
mask_not = cv.bitwise_not(mask)
cv.imshow("mask_not", mask_not)

# 利用蒙版,将人物部分抠出
people = cv.bitwise_and(src, src, mask=mask_not)
cv.imshow("people", people)

# 取一张背景图,并截取与mask相同尺寸的部分
scene = cv.imread("E:/_Image/OpenCVTest/scene.jpg")
dstScene = scene[:people.shape[0], :people.shape[1], :]
cv.imshow("dstScene", dstScene)

# 利用蒙版,在背景图中扣掉待填充的人物蒙版部分
sceneBackground = cv.bitwise_and(dstScene, dstScene, mask=mask)
cv.imshow("sceneBackground", sceneBackground)

# 或操作,将人物融入背景图中
finalImage = cv.bitwise_or(sceneBackground, people)
cv.imshow("finalImage", finalImage)

# 等待键盘输入 释放内存
cv.waitKey(0)
cv.destroyAllWindows()

JS代码

<template>
  <div>
    <p>色彩空间的转换及应用</p>
    <p id="status">OpenCV.js is loading...</p>
    <div class="inputoutput">
      <img id="imageSrc" src="imgs/tinygreen.jpg" />
      <img id="imageSrc2" src="imgs/scene.jpg" />
    </div>
    <div class="inputoutput">
      <canvas id="canvasOutput"></canvas>
      <div class="caption">canvasOutput</div>
    </div>
  </div>
</template>

<script>
export default {
  name: "day09",
  mounted() {
    this.init();
  },
  destoryed() {},
  data() {
    return {
      mats: [],
    };
  },
  methods: {
    init() {
      setTimeout(() => {
        if (window.cv) {
          this.onOpenCvReady(window.cv);
        } else {
          this.init();
        }
      }, 500);
    },
    onOpenCvReady(cv) {
      document.getElementById("status").innerHTML = "OpenCV.js is ready.";

      // 官方文档链接:https://docs.opencv.org/4.5.0/db/d64/tutorial_js_colorspaces.html

      let src = this.createMat(cv, 1, { name: "imageSrc" });

      // 转化到 HSV 色彩空间
      let hsv = this.createMat(cv, 2);
      cv.cvtColor(src, hsv, cv.COLOR_RGB2HSV);

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

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

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

      // 取一张背景图,并截取与mask相同尺寸的部分
      let scene = this.createMat(cv, 1, { name: "imageSrc2" });
      let rect = new cv.Rect(0, 0, people.cols, people.rows);
      let dstScene = this.createMat(cv, 2);
      dstScene = scene.roi(rect);

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

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

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

      // 销毁所有 mat
      this.destoryAllMats();
    },
    createMat(cv, type, ops) {
      switch (type) {
        case 1:
          if (ops && ops.name) {
            let mat = cv.imread(ops.name);
            this.mats.push(mat);
            return mat;
          }
          break;
        case 2: {
          let mat = new cv.Mat();
          this.mats.push(mat);
          return mat;
        }
        case 3:
          if (ops && ops.rows && ops.cols && ops.type && ops.initValue) {
            let mat = new cv.Mat(ops.rows, ops.cols, ops.type, ops.initValue);
            this.mats.push(mat);
            return mat;
          }
          break;
        default:
          break;
      }
    },
    destoryAllMats() {
      this.mats.forEach((item) => {
        item.delete();
      });
    },
  },
};
</script>

<style lang="scss" scoped>
</style>

官方文档链接:https://docs.opencv.org/4.5.0/db/d64/tutorial_js_colorspaces.html

结果展示

返回总目录

OpenCV4学习笔记 - 目录

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

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Apple_Coco

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

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

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

打赏作者

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

抵扣说明:

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

余额充值