【python】OpenCV——Color Correction

在这里插入图片描述

文章目录

  • 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.mfbz.cn/a/730774.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【2024德国工作】外国人在德国找工作是什么体验?

挺难的,德语应该是所有中国人的难点。大部分中国人进德国公司要么是做中国业务相关,要么是做技术领域的工程师。先讲讲人在中国怎么找德国的工作,顺便延申下,德国工作的真实体验,最后聊聊在今年的德国工作签证申请条件…

网络与协议安全复习 - 电子邮件安全

文章目录 PGP(Pretty Good Privacy)功能 S/MIME(Secure/Multipurpose Internet Mail Extensions)DKIM(Domain Keys Identified Mail) PGP(Pretty Good Privacy) 使用符号: Ks:会话密钥、KRa:A 的私钥、KUa:A 的公钥、EP&#xff…

Android开发系列(六)Jetpack Compose之Box

Box是一个用来组合和控制子元素布局的组件。它可以在一个矩形区域内排列一个或多个子元素,并根据所提供的参数来控制它们的位置、大小和样式。 Box的功能类似传统的FrameLayout。 下面通过示例了解Box的使用方法,首先看一个最简单的示例,如下…

永磁同步电机驱动死区补偿

1 死区效应及补偿 1. 1 死区效应 在本文的电机控制嵌入式系统中,逆变器为三 相电压型桥式逆变电路,如图 1 所示。 在理想状态 下,上桥臂和下桥臂的控制信号满足互补通断原则, 即上桥臂开通时,下桥臂关断,反之亦然。 而在实际 应用中,开关管的通断需要一定的开通时…

大语言模型-Transformer

目录 1.概述 2.作用 3.诞生背景 4.历史版本 5.优缺点 5.1.优点 5.2.缺点 6.如何使用 7.应用场景 7.1.十大应用场景 7.2.聊天机器人 8.Python示例 9.总结 1.概述 大语言模型-Transformer是一种基于自注意力机制(self-attention)的深度学习…

如何使用Windows备份轻松将数据转移到新电脑?这里有详细步骤

序言 我们都知道那种买了一台新电脑,就想直接上手的感觉。我记得在过去的日子里,要花几个小时传输我的文件,并试图复制我的设置。在当今传输数据的众多方法中,Windows备份提供了一个简单可靠的解决方案。 登录到你的Microsoft帐户 Microsoft在传输过程中使用其云存储来保…

NGINX_六 nginx 日志文件详解

六 nginx 日志文件详解 nginx 日志文件分为 **log_format** 和 **access_log** 两部分log_format 定义记录的格式,其语法格式为log_format 样式名称 样式详情配置文件中默认有log_format main $remote_addr - $remote_user [time_local] "req…

二,SpringFramework

二、SpringFramework实战指南 目录 一、技术体系结构 1.1 总体技术体系1.2 框架概念和理解 二、SpringFramework介绍 2.1 Spring 和 SpringFramework概念2.2 SpringFramework主要功能模块2.3 SpringFramework 主要优势 三、Spring IoC容器和核心概念 3.1 组件和组件管理概念3…

超越GPT-4o!新王Claude 3.5 Sonnet来啦!免费使用

目录 01 比GPT-4o更智能,比Claude 3 Opus快两倍 02 最强视觉Model 03 使用Claude的新方式:Artifacts 04 安全性和透明度 Anthropic刚刚发布了全新大模型Claude 3.5 Sonnet,号称是迄今为止最智能的模型。一文几步教你注册使用Claude 3.5 S…

硬件开发笔记(二十一):外部搜索不到的元器件封装可尝试使用AD21软件的“ManufacturerPart Search”功能

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/139869584 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

英文字母表

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 namespace 英文字母表 {public partial class Form1 : Form{public Form1(){InitializeComponent();}private void Form1_Load(object sender, EventArgs e){foreach (var item in panel1.Controls){if (item ! null)…

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

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

【大数据】—二手车用户数据可视化分析案例

项目背景 在当今的大数据时代,数据可视化扮演着至关重要的角色。随着信息的爆炸式增长,我们面临着前所未有的数据挑战。这些数据可能来自社交媒体、商业交易、科学研究、医疗记录等各个领域,它们庞大而复杂,难以通过传统的数据处…

掌握数据魔方:Xinstall引领ASA全链路数据归因新纪元

一、引言 在数字化时代,数据是App推广和运营的核心驱动力。然而,如何准确获取、分析并应用这些数据,却成为了许多开发者和营销人员面临的痛点。Xinstall作为一款专业的App全渠道统计服务商,致力于提供精准、高效的数据解决方案&a…

Linux开发讲课8--- linux的5种IO模型

一、这里IO是什么 操作系统为了保护自己,设计了用户态、内核态两个状态。应用程序一般工作在用户态,当调用一些底层操作的时候(比如 IO 操作),就需要切换到内核态才可以进行 服务器从网络接收的大致流程如下&#xff1…

拍卖商城开发要点源码及功能分析

要创建一个正规的拍卖商城平台,需要遵循一系列步骤,确保平台的合法性、专业性和用户体验。以下是一个详细的步骤指南: 一、明确平台定位与规划 确定拍卖商城平台的目标市场、用户群体和主要拍卖品类。 制定平台的发展规划和战略目标&#…

gorm 学习笔记 五:自定义数据类型和枚举

一:Json类型 Info保存到数据库时,通过Value()转化为json,读取出来的时候 json字符串自动转成结构体Info type Info struct {Status string json:"status"Addr string json:"addr"Age int json:"age"…

无人机比赛有哪些?

无人机比赛项目可是多种多样,精彩纷呈呢! 常见的比赛项目包括S形绕桩赛、平台起降赛、应用航拍、投掷物品和定点飞行等。这些项目不仅考验无人机的性能,更考验飞行员的操控技巧。 在S形绕桩赛中,飞行员需要操控无人机快速而准确…

云计算技术高速发展,优势凸显

云计算是一种分布式计算技术,其特点是通过网络“云”将巨大的数据计算处理程序分解成无数个小程序,并通过多部服务器组成的系统进行处理和分析这些小程序,最后将结果返回给用户。它融合了分布式计算、效用计算、负载均衡、并行计算、网络存储…

初识 GPT-4 和 ChatGPT

文章目录 LLM 概述理解 Transformer 架构及其在 LLM 中的作用解密 GPT 模型的标记化和预测步骤 想象这样⼀个世界:在这个世界里,你可以像和朋友聊天⼀样快速地与计算机交互。那会是怎样的体验?你可以创造出什么样的应用程序?这正是…