首页 > 其他分享 >OpenCV中的浅拷贝和深拷贝

OpenCV中的浅拷贝和深拷贝

时间:2024-07-10 13:28:06浏览次数:15  
标签:img image param OpenCV 拷贝 矩形 绘制

文章目录


前言

在数字图像处理中,针对读取到的一张图像,需要反复利用这张图像做各种的变换,以满足我们项目的需求。在这之前,最容易忽略的一点就是图像之间的拷贝问题,其中的浅拷贝和深拷贝不仅影响数据的存储方式,还直接关系到内存管理和数据修改的影响范围。

一、浅拷贝

浅拷贝是指创建一个新的对象,但这个新对象会引用原始对象中的数据(或指向原始数据的指针)。这意味着,如果原始数据发生变化,通过浅拷贝得到的数据也会发生变化,因为它们实际上指向的是同一块内存地址。

在OpenCV中,当使用赋值操作符(=)时,通常执行的是浅拷贝。

二、深拷贝

深拷贝则是创建一个全新的对象,并复制原始对象中的所有数据到新对象中。这样,原始对象和新对象拥有独立的内存地址和数据。因此,对原始对象的修改不会影响到通过深拷贝得到的新对象。

OpenCV的C++接口提供了clone()方法,但在Python中,可以直接使用NumPy的深拷贝机制。

三、比较

此处举一个简单的例子,当我们想在输入的图像中分别实现画矩形和画圆的操作时,首先我们定义两个函数用于绘制矩形和圆:

def draw_rectangle(image, top_left, bottom_right, color, thickness=2):
    """
    在图像上绘制矩形
    :param image: 要绘制的图像
    :param top_left: 矩形左上角的坐标 (x, y)
    :param bottom_right: 矩形右下角的坐标 (x, y)
    :param color: 矩形的颜色,格式为 (B, G, R)
    :param thickness: 矩形边框的厚度
    :return: 绘制了矩形的图像
    """
    cv2.rectangle(image, top_left, bottom_right, color, thickness)
    return image

def draw_circle(image, center, radius, color, thickness=2, fill=False):
    """
    在图像上绘制圆
    :param image: 要绘制的图像
    :param center: 圆的中心坐标 (x, y)
    :param radius: 圆的半径
    :param color: 圆的颜色,格式为 (B, G, R)
    :param thickness: 圆边框的厚度,如果fill=True,则此参数将被忽略
    :param fill: 是否填充圆
    :return: 绘制了圆的图像
    """
    if fill:
        cv2.circle(image, center, radius, color, -1)
    else:
        cv2.circle(image, center, radius, color, thickness)
    return image

我们均使用浅拷贝调用函数的时候,得到的结果不管是原图还是绘制之后的图像均被绘制了图像,这与我们的目的相反。

image = cv2.imread('D:/test.png')
# 绘制矩形
rect_img = image
rect_image = draw_rectangle(rect_img, (50, 50), (200, 200), (0, 0, 0), 3)
# 绘制圆
cir_img = image
circle_image = draw_circle(cir_img, (150, 150), 50, (255, 255, 255), 3, False)

在这里插入图片描述

我们均使用深拷贝调用函数的时候,得到的结果互不干扰

image = cv2.imread('D:/test.png')
# 绘制矩形
rect_img = image.copy()
rect_image = draw_rectangle(rect_img, (50, 50), (200, 200), (0, 0, 0), 3)
# 绘制圆
cir_img = image.copy()
circle_image = draw_circle(cir_img, (150, 150), 50, (255, 255, 255), 3, False)

在这里插入图片描述


总结

区分深拷贝和浅拷贝主要是为了理解数据是如何在内存中存储和管理的,以及如何在不同的对象或函数之间安全地传递数据。浅拷贝可能更节省内存(因为它不复制数据),但在某些情况下,如果原始数据被意外修改,可能会导致数据不一致的问题。深拷贝虽然会消耗更多的内存,但它提供了更高的数据安全性和独立性。

标签:img,image,param,OpenCV,拷贝,矩形,绘制
From: https://blog.csdn.net/qq_42591591/article/details/140321326

相关文章

  • Opencv中的直方图均衡
    cv2.equalizeHist()cv2.equalizeHist()是OpenCV中的一个函数,用于图像的直方图均衡化。直方图均衡化是一种改善图像对比度的方法,特别是当图像的背景和前景都太亮或太暗时,这种方法非常有用。它通过扩展图像的直方图来有效地增加图像的全局对比度,特别是当图像的有用数据的对......
  • JavaScript复习记录(2)— 浅拷贝&深拷贝
    1、前情概要1.1、基本数据类型    Number、String、Boolean、Null、Undefined、Symbol、BigInt。基本数据类型是直接存储在栈中的数据。1.2、引用数据类型    Object、Array、Function、Date、RegExp、Map、Set、WeekMap、WeekSet、Promise、Error、Buffe......
  • opencv读取视频文件夹内视频的名字_时长_帧率_分辨率写入excel-cnblog
    看视频的时候有的视频文件名贼长。想要翻看,在文件夹里根本显示不出来,缩短又会丢失一些信息,所以我写了一份Python代码,直接获取视频的名字,时长,帧率,还有分辨率写到excel里。实际效果如下图。可以看到需要的大致信息都被提取出来了接下来直接上代码importosimportxlsxwr......
  • js浅拷贝与深拷贝的区别和实现方式
           ......
  • 浅拷贝和深拷贝的区别
    一、数据类型在讨论深浅拷贝之前,我们先说说数据类型,因为深浅拷贝与数据类型有关。数据类型分为基本数据类型(String、Number、Boolean、Null、Undefined、Symbol(es6引入的一种类型))和引用数据类型(Object、Array、Function)。基本数据类型特点:直接存储在栈中;引用数据类型:它真......
  • 简述 JS 中对象的创建和拷贝
    在JavaScript中,对象是一种非常重要且灵活的数据结构,用于存储多个值(属性)和方法(函数)对象的创建和拷贝是日常开发中经常涉及的操作,对于业务逻辑的准确实现有着重要的作用本文将简要概括JavaScript中对象的创建和拷贝方式,都是一些非常基础的知识,大家看个乐就好~目录对象的作......
  • 基于opencv + GPU cuda的光流算法demo
    该demo来自learnopencv.com网站,是作为opencvcuda模块的启蒙示例。看来这是一个简单的例子,但是由于从未接触过opencvcuda图像处理,我个人仍感觉比较新颖和有趣,特别是运行效果很惊奇,这里和大家一起学习解读以下。想看一手内容可以在网络直接搜索GettingStartedWithOpencvcuda......
  • 关于浅拷贝,深拷贝以及深拷贝的实现方法
    浅拷⻉:浅拷⻉会在堆上创建⼀个新的对象(区别于引⽤拷⻉的⼀点),不过,如果原对象内部的属性是引⽤类型的话,浅拷⻉会直接复制内部对象的引⽤地址,也就是说拷⻉对象和原对象共⽤同⼀个内部对象。深拷⻉:深拷⻉会完全复制整个对象,包括这个对象所包含的内部对象。我们知道在Java中......
  • Python OpenCv对规则物体进行实时检测
    前言很多情况需要对物体进行检测,常规的方法也有很多种。但是检测出来的边缘一般都是非常多,结果也是非常杂乱的,显然这种结果不是我们想要的。如果颜色相较于背景非常鲜艳的可以调节hsv阈值再进行检测,如果是一直在运动的物体可以通过帧差法进行物体检测,还有很多高深的算法也可以进......
  • Linux系统配置Opencv+cuda+ffmpeg开发环境,-217:Gpu API call unknown error code问题
    Opencv是当前比较热门的图像处理开源算法库,但是随着深度学习在图像存储里领域的大放异彩,基于python的图像处理和深度学习算法大有超越opencv的趋势。opencv在最近的版本更新中,重点都放在了人工智能算法方面,本文介绍linux环境下配置支持GPU/cuda的ffmpeg和opencv开发环境,并将其中遇......