【python】OpenCV——Color Correction

news2024/12/23 6:01:37

在这里插入图片描述

文章目录

  • cv2.aruco 介绍
  • imutils.perspective.four_point_transform 介绍
  • skimage.exposure.match_histograms 介绍
  • 牛刀小试
  • 遇到的问题

参考学习来自 OpenCV基础(18)使用 OpenCV 和 Python 进行自动色彩校正

cv2.aruco 介绍

在这里插入图片描述

一、cv2.aruco模块概述

cv2.aruco 是 OpenCV 库中用于 ArUco 标记检测和识别的模块。ArUco 是一种基于 OpenCV 的二进制标记系统,用于多种计算机视觉应用,如姿态估计、相机校准、机器人导航和增强现实等。

以下是关于 cv2.aruco 的中文文档概要,按照参考文章中的信息进行整理和归纳:

一、ArUco 标记概述

ArUco 标记是带有黑色边框的二进制正方形图像,内部主体为白色,标记根据特定的编码变化。
ArUco 标记由 ArUco 字典、标记大小和标记 ID 组成。例如,一个 4x4_100 字典由 100 个标记组成,4x4 标记大小意味着标记由 25 位组成,每个标记将有一个唯一的 ID。

二、主要函数与参数

(1)cv2.aruco.detectMarkers()

  • 功能:检测图像中的 ArUco 标记。
  • 参数:
    • 输入图像:包含 ArUco 标记的图像。
    • 字典:用于搜索的 ArUco 字典。
    • 参数(可选):检测参数,如 cv2.aruco.DetectorParameters()。
  • 返回值:
    • 标记角:检测到的标记的四个角的位置坐标。
    • 标记 ID:检测到的标记的 ID。
    • 拒绝标记(可选):未满足检测条件的标记信息。

(2)cv2.aruco.drawDetectedMarkers()

  • 功能:在图像上绘制检测到的 ArUco 标记。

  • 参数:

    • 输入图像:包含 ArUco 标记的图像。
    • 标记角:检测到的标记的四个角的位置坐标。
    • 边界颜色(可选):绘制标记边界的颜色。
  • 返回值:绘制了标记的图像。

(3)cv2.aruco.getPredefinedDictionary()

  • 功能:获取预定义的 ArUco 字典。

  • 参数:字典类型(如 aruco.DICT_ARUCO_ORIGINAL)。

  • 返回值:预定义的 ArUco 字典。

三、检测过程与参数调整

阈值化:检测的第一步是对输入图像进行阈值化。这可以通过调整 cv2.aruco.DetectorParameters() 中的相关参数来完成,如 adaptiveThreshWinSizeMin、adaptiveThreshWinSizeMax 和 adaptiveThreshWinSizeStep。

角点细化:为了提高角点检测的精度,可以使用 cornerRefinementMethod 和 cornerRefinementWinSize 参数进行角点细化。

四、使用示例

以下是一个简单的示例,演示了如何使用 cv2.aruco 检测和可视化 ArUco 标记:

import cv2  
import cv2.aruco as aruco  
  
# 读取图片  
img = cv2.imread("marker.jpg")  
  
# 创建字典  
dictionary = aruco.getPredefinedDictionary(aruco.DICT_ARUCO_ORIGINAL)  
  
# 检测标记  
corners, ids, _ = aruco.detectMarkers(img, dictionary)  
  
# 可视化标记  
img_with_markers = aruco.drawDetectedMarkers(img, corners)  
  
# 显示结果  
cv2.imshow("ArUco detection", img_with_markers)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

五、注意事项

  • 确保已正确安装 OpenCV,并包含 cv2.aruco 模块。

  • 根据具体应用需求选择合适的 ArUco 字典和标记大小。

  • 调整检测参数以优化标记检测性能。

imutils.perspective.four_point_transform 介绍

使用前先安装 pip install imutils

imutils.perspective.four_point_transform 是 OpenCV 图像处理库的一个辅助工具,用于实现透视变换(Perspective Transformation)。透视变换可以将一个图像从一个视角转换到另一个视角,这在图像校正、文档扫描、车牌识别等任务中非常有用。

以下是关于 imutils.perspective.four_point_transform 函数的详细解释和用法:

一、函数定义

imutils.perspective.four_point_transform 函数需要两个主要参数:

  • image:要进行透视变换的原始图像。

  • pts:包含图像中感兴趣区域(ROI)四个顶点的坐标列表。这四个点定义了原始图像中的一个四边形区域,该区域将被变换成一个矩形区域。

二、使用步骤

a. 读取图像
首先,使用 OpenCV 的 cv2.imread() 函数读取要进行透视变换的图像。

b. 确定变换点
然后,需要确定要进行透视变换的 ROI 的四个顶点。这可以通过各种方法实现,如边缘检测、轮廓查找、角点检测等。

c. 调用 four_point_transform 函数
将原始图像和四个顶点的坐标列表传递给 imutils.perspective.four_point_transform 函数。函数将返回一个经过透视变换后的新图像。

d. 显示或保存变换后的图像
使用 OpenCV 的 cv2.imshow() 函数显示变换后的图像,或者使用 cv2.imwrite() 函数将其保存为文件。

三、示例代码

以下是一个简单的示例代码,展示了如何使用 imutils.perspective.four_point_transform 函数进行透视变换:

import cv2  
import numpy as np  
import imutils  
 
# 读取图像  
image = cv2.imread('input.jpg')  
  
# 假设我们已经通过某种方法找到了 ROI 的四个顶点,这里我们直接给出坐标  
pts = np.array([[100, 100], [300, 100], [300, 300], [100, 300]], dtype="float32")  
  
# 进行透视变换  
warped = imutils.perspective.four_point_transform(image, pts)  
  
# 显示变换后的图像  
cv2.imshow("Warped", warped)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

四、注意事项

  • 确保 pts 列表中的坐标点按照正确的顺序排列(通常是左上角、右上角、右下角、左下角)。

  • 透视变换的结果可能会受到原始图像中 ROI 的形状和大小的影响。因此,在实际应用中,可能需要通过调整 ROI 的位置和大小来优化变换结果。

skimage.exposure.match_histograms 介绍

在这里插入图片描述

可参考 【python】OpenCV—Histogram Matching(9.2)

牛刀小试

素材来自于

链接:https://pan.baidu.com/s/1ja5RZUiV5Hyu-Z65JEJWzg 
提取码:123a
# -----------------------------
#   USAGE
# -----------------------------
# python color_correction.py
# -----------------------------
#   IMPORTS
# -----------------------------
# Import the necessary packages
from imutils.perspective import four_point_transform
from skimage import exposure
import numpy as np
import argparse
import imutils
import cv2
import sys


# -----------------------------
#   FUNCTIONS
# -----------------------------
def find_color_card(image, colors, savename=None):
    # Load the ArUCo dictionary, grab the ArUCo parameters and detect the markers in the input image
    arucoDict = cv2.aruco.Dictionary_get(cv2.aruco.DICT_ARUCO_ORIGINAL)
    arucoParams = cv2.aruco.DetectorParameters_create()
    (corners, ids, rejected) = cv2.aruco.detectMarkers(image, arucoDict, parameters=arucoParams)

    # Plot corners
    if savename:
        image_copy = image.copy()
        for i in range(len(corners)):  # traverse corners
            for j in range(4):  # traverse coordinates
                cv2.circle(image_copy, center=(int(corners[i][0][j][0]), int(corners[i][0][j][1])),
                           radius=10, color=colors[i], thickness=-1)
                cv2.imwrite(savename, image_copy)

    # Try to extract the coordinates of the color correction card
    try:
        # Otherwise, this means that the four ArUCo markers have been found and
        # so continue by flattening the ArUCo IDs list
        ids = ids.flatten()
        # Extract the top-left marker
        i = np.squeeze(np.where(ids == 923))  # 3
        topLeft = np.squeeze(corners[i])[0]  # array([111., 123.], dtype=float32)
        # Extract the top-right marker
        i = np.squeeze(np.where(ids == 1001))  # 2
        topRight = np.squeeze(corners[i])[1]  # array([430., 124.], dtype=float32)
        # Extract the bottom-right marker
        i = np.squeeze(np.where(ids == 241))  # 1
        bottomRight = np.squeeze(corners[i])[2]  # array([427., 516.], dtype=float32)
        # Extract the bottom left marker
        i = np.squeeze(np.where(ids == 1007))  # 0
        bottomLeft = np.squeeze(corners[i])[3]  # array([121., 520.], dtype=float32)
    # The color correction card could not be found, so gracefully return
    except:
        return None
    # Build the list of reference points and apply a perspective transform to obtain a top-down,
    # birds-eye-view of the color matching card
    cardCoords = np.array([topLeft, topRight, bottomRight, bottomLeft])
    """ for reference
    array([[111., 123.],
       [430., 124.],
       [427., 516.],
       [121., 520.]], dtype=float32)
    """
    card = four_point_transform(image, cardCoords)
    # Return the color matching card to the calling function
    return card


if __name__ == "__main__":
    # colors for corners
    colors = [
        [0, 0, 255],
        [0, 125, 255],
        [0, 255, 255],
        [0, 255, 0]
    ]

    # Load the reference image and input images from disk
    print("[INFO] Loading images...")
    ref = cv2.imread("./reference.jpg")  # (4032, 3024, 3)
    image = cv2.imread("./examples/03.jpg")  # (4032, 3024, 3)

    # Resize the reference and input images
    ref = imutils.resize(ref, width=600)  # (800, 600, 3)
    image = imutils.resize(image, width=600)  # (800, 600, 3)

    # Display the reference and input images to the screen
    cv2.imshow("Reference", ref)
    cv2.imshow("Input", image)

    # Find the color matching card in each image
    print("[INFO] Finding color matching cards...")
    refCard = find_color_card(ref, colors, "refCardPlot.jpg")  # (397, 319, 3)
    imageCard = find_color_card(image, colors, "imageCardPlot.jpg")  # (385, 306, 3)

    # If the color matching card is not found in either the reference or the input image, gracefully exit the program
    if refCard is None or imageCard is None:
        print("[INFO] Could not find color matching cards in both images! Exiting...")
        sys.exit(0)

    # Show the color matching card in the reference image and the in the input image respectively
    cv2.imshow("Reference Color Card", refCard)
    cv2.imshow("Input Color Card", imageCard)

    # cv2.imwrite("reference_color_card.jpg", refCard)
    # cv2.imwrite("input_color_card.jpg", imageCard)

    # Apply histogram matching from the color matching card in the reference image
    # to the color matching card in the input image
    print("[INFO] Matching images...")
    # imageCard = exposure.match_histograms(imageCard, refCard, multichannel=True)
    imageCard = exposure.match_histograms(imageCard, refCard, channel_axis=-1)

    # Show the input color matching card after histogram matching
    cv2.imshow("Input Color Card After Matching", imageCard)
    # cv2.imwrite("input_color_card_after_matching.jpg", imageCard)
    cv2.waitKey(0)

reference.jpg

在这里插入图片描述
03.jpg

在这里插入图片描述
refCardPlot.jpg

在这里插入图片描述

reference 的 corners

(array([[[120., 486.],
        [155., 485.],
        [156., 519.],
        [121., 520.]]], dtype=float32), 
array([[[393., 482.],
        [427., 482.],
        [427., 516.],
        [393., 516.]]], dtype=float32), 
array([[[395., 124.],
        [430., 124.],
        [430., 161.],
        [395., 161.]]], dtype=float32), 
array([[[111., 123.],
        [147., 124.],
        [148., 160.],
        [111., 160.]]], dtype=float32))

reference 的 ids

array([[1007],
       [ 241],
       [1001],
       [ 923]], dtype=int32)

reference 的 rejected

len(rejected)
76

1007 左下角,红色

241 右下角,橙色

1001 右上角,黄色

923 右下角,绿色

imageCardPlot.jpg

在这里插入图片描述

透视变换 four_point_transform 后

reference_color_card.jpg

在这里插入图片描述

input_color_card.jpg

在这里插入图片描述

input_color_card_after_matching.jpg

在这里插入图片描述

遇到的问题

问题1:AttributeError: module ‘cv2.aruco’ has no attribute ‘Dictionary_get’

解决办法:pip install opencv-contrib-python==4.6.0.66

问题2:TypeError: rescale() got an unexpected keyword argument ‘multichannel‘

解决方法:TypeError: rescale() got an unexpected keyword argument ‘multichannel‘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1847593.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关于微信小程序取消获取用户昵称的一些思考

官方说明,有部分小程序乱用授权,强迫用户提交头像和昵称。 核心是微信担心用户信息被滥用。 其一 ,微信头像经常是本人真是照片,在现在人工智能算法的加持下,人脸数据太容易被套取。 其二,微信名称同理&…

node版本过高出现ERR_OSSL_EVP_UNSUPPORTED错误

错误原因: 新版本的nodejs使用的openssl和旧版本不同,导致出错 解决方法: 1.将node版本重新换回16.x 2 windows 下 在package.json文件下添加set NODE_OPTIONS--openssl-legacy-provider && "scripts": {"dev"…

手把手教你java CPU飙升300%如何优化

背景 今天有个项目运行一段时间后,cpu老是不堪负载。 排查 top 命令 TOP 命令 top t 按cpu 排序 top m 按内存使用率排序 从上面看很快看出是 pid 4338 这个进程资源消耗很高。 top -Hp pid top -Hp 4338 找到对应线程消耗的资源shftp cpu占用进行排序&#xf…

拒绝零散碎片, 一文理清MySQL的各种锁

系列文章目录 学习MySQL先有全局观,细说其发展历程及特点 Mysql常用操作,谈谈排序与分页 拒绝零散碎片, 一文理清MySQL的各种锁(收藏向) 系列文章目录一、MySQL的锁指什么二、排他与共享三、全局锁(Global…

数据仓库的实际应用示例-广告投放平台为例

数据仓库的数据分层通常包括以下几层: ODS层:存放原始数据,如日志数据和结构化数据。DWD层:进行数据清洗、脱敏、维度退化和格式转换。DWS层:用于宽表聚合值和主题加工。ADS层:面向业务定制的应用数据层。…

从零入手人工智能(4)—— 逻辑回归

1.小故事 一家金融科技公司,公司的首席执行官找到团队提出了一个紧迫的问题:“我们如何提前知道哪些客户可能会违约贷款?” 这让团队陷入了沉思,经过激烈讨论团队中的数据分析师提议:“我们可以尝试使用逻辑回归来预测…

解决双击bootstrap.bat没有生成b2.exe文件

双击bootstrap.bat但是并没有没有生成b2.exe文件,会报如下错误: "cl" 不是内部或外部命令,也不是可运行的程序 或批处理文件。D:\cppsoft\boost_1_85_0\tools\build\src\engine>dir *.exe 驱动器 D 中的卷是 Data 卷的序列号是…

六、在Qt下通过PCL在VTK9.3.0下显示自己的pcd点云文件

前几天刚整理好VTK8.2.0,发现我们的项目使用的PCL自带的VTK是9.3.0的,脸黑了快 VTK8.2.0可参考该篇博文:五、在Qt下加载QVTKWidget控件(VTK8.2.0),生成Visual Studio项目,显示点云(C…

如何基于项目人力和管线方案选择FGUI和UGUI

1)如何基于项目人力和管线方案选择FGUI和UGUI 2)TMP字体出包丢失字体描边 3)如何将一张贴图经过Shader处理后的结果输出给另外一个Shader使用 4)为什么我的水这么干净,和UE教程里的有差别 这是第390篇UWA技术知识分享的…

ECharts Y轴倒置,X轴顶部,图表反向

1.配置: xAxis:{position: ‘top’} //让x轴在顶部 yAxis: { inverse:true} //让Y轴坐标为反向坐标 2.将数据的只转换成负值(不建议),显示的时候formatter里面在显示正值(不建议)

强化安全新篇章:韶关石油化工可燃气体报警器年检解析

韶关,这座位于广东省北部的城市,近年来在石油化工行业取得了显著的发展。 随着一批批大型石化企业的进驻和投产,韶关不仅成为了区域性的石化产业基地,也为地方经济带来了强劲的增长动力。 然而,随着石化产业的快速发…

使用asyncua模块的subscribe_data_change监控opcua的Server节点数据变化

报错信息如下; ERROR:asyncua.common.subscription:DataChange subscription created but handler has no datachange_notification method 上述报错原因在于创建监控句柄SubscriptionHandler类时,节点数据变化的函数名称有问题,不是默认的da…

【NLP练习】Transformer实战-单词预测

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 任务:自定义输入一段英文文本进行预测 一、定义模型 from tempfile import TemporaryDirectory from typing import Tuple from torch import nn…

DVWA 靶场 Open HTTP Redirect 通关解析

前言 DVWA代表Damn Vulnerable Web Application,是一个用于学习和练习Web应用程序漏洞的开源漏洞应用程序。它被设计成一个易于安装和配置的漏洞应用程序,旨在帮助安全专业人员和爱好者了解和熟悉不同类型的Web应用程序漏洞。 DVWA提供了一系列的漏洞场…

Nuxt快速学习开发---Nuxt3视图Views

Views Nuxt提供了几个组件层来实现应用程序的用户界面 默认情况下&#xff0c;Nuxt 会将app.vue文件视为入口点并为应用程序的每个路由呈现其内容 应用程序.vue <template> <div> <h1>Welcome to the homepage</h1> </div> </template> …

湖南科技大学24计算机考研情况,软工学硕考数二,分数线290分,录取均分321分!

湖南科技大学&#xff08;Hunan University of Science and Technology&#xff09;坐落在伟人故里、人文圣地湘潭&#xff0c;处于长株潭核心区域&#xff0c;比邻湘潭九华经济技术开发区&#xff08;国家级&#xff09;&#xff0c;是应急管理部、国家国防科技工业局与湖南省…

复分析——第6章—— Γ 函数和 ζ 函数(E.M. Stein R. Shakarchi)

第6章 Γ函数和Ζ函数(The Gamma and Zeta Functions) 毫不夸张地说&#xff0c;Γ函数和Ζ函数是数学中最重要的非初等函数之一。Γ函数在自然界中无处不在。它出现在大量计算中&#xff0c;并以分析中出现的大量恒等式为特征。对此的部分解释可能在于Γ函数的基本结构特性&…

Nginx HTTPS(证书) 部署实战

一、申请证书与认证 要搭建https服务首先需有SSL证书&#xff0c;证书通常是在第三方申请&#xff0c;在阿里云的安全服务中有SSL证书这一项&#xff0c;可以在里面申请免费的证书。也可以在自己电脑中生成&#xff0c;虽然也能完成加密&#xff0c;但是浏览器是不认可的&…

编译 CanMV 固件

前言 上一章节中已经搭建好了基于 CanMV 的 C 开发环境&#xff0c;这么一来便可以进行基于 C 语言和 FreeRTOS 的应用开发或者编译基于 MicroPython 语法的应用开发方式所需的 CanMV 固件&#xff0c;本 章就将带领读者体验一下 CanMV 固件的编译流程。 本章分为如下几个小节&…

Java面试题:mysql执行速度慢的原因和优化

Sql语句执行速度慢 原因 聚合查询 多表查询 表数据量过大查询 深度分页查询 分析 sql的执行计划 可以使用EXPLAIN或者DESC获取Mysql如何执行SELECT语句的信息 直接在select语句前加关键字explain/desc 得到一个执行信息表 信息字段分析 possible_keys:可能使用到的索…