当前位置: 首页 > news >正文

【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 imagearucoDict = 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 cornersif savename:image_copy = image.copy()for i in range(len(corners)):  # traverse cornersfor j in range(4):  # traverse coordinatescv2.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 cardtry:# Otherwise, this means that the four ArUCo markers have been found and# so continue by flattening the ArUCo IDs listids = ids.flatten()# Extract the top-left markeri = np.squeeze(np.where(ids == 923))  # 3topLeft = np.squeeze(corners[i])[0]  # array([111., 123.], dtype=float32)# Extract the top-right markeri = np.squeeze(np.where(ids == 1001))  # 2topRight = np.squeeze(corners[i])[1]  # array([430., 124.], dtype=float32)# Extract the bottom-right markeri = np.squeeze(np.where(ids == 241))  # 1bottomRight = np.squeeze(corners[i])[2]  # array([427., 516.], dtype=float32)# Extract the bottom left markeri = np.squeeze(np.where(ids == 1007))  # 0bottomLeft = np.squeeze(corners[i])[3]  # array([121., 520.], dtype=float32)# The color correction card could not be found, so gracefully returnexcept: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 cardcardCoords = np.array([topLeft, topRight, bottomRight, bottomLeft])""" for referencearray([[111., 123.],[430., 124.],[427., 516.],[121., 520.]], dtype=float32)"""card = four_point_transform(image, cardCoords)# Return the color matching card to the calling functionreturn cardif __name__ == "__main__":# colors for cornerscolors = [[0, 0, 255],[0, 125, 255],[0, 255, 255],[0, 255, 0]]# Load the reference image and input images from diskprint("[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 imagesref = 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 screencv2.imshow("Reference", ref)cv2.imshow("Input", image)# Find the color matching card in each imageprint("[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 programif 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 respectivelycv2.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 imageprint("[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 matchingcv2.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‘

解决方法:将multichannel=True改成channel_axis=-1

相关文章:

【python】OpenCV—Color Correction

文章目录 cv2.aruco 介绍imutils.perspective.four_point_transform 介绍skimage.exposure.match_histograms 介绍牛刀小试遇到的问题 参考学习来自 OpenCV基础(18)使用 OpenCV 和 Python 进行自动色彩校正 cv2.aruco 介绍 一、cv2.aruco模块概述 cv2.…...

Java基础知识整理笔记

目录 1.关于Java概念 1.1 谈谈对Java的理解? 1.2 Java的基础数据类型? 1.3 关于面向对象的设计理解 1.3.1 面向对象的特性有哪些? 1.3.2 重写和重载的区别? 1.3.3 面向对象的设计原则是什么? 1.4 关于变量与方…...

知识图谱——Neo4j数据库实战

数据与代码链接见文末 1.Neo4j数据库安装 JDK 安装:https://www.oracle.com/java/technologies/javase-downloads.html Neo4j 安装:https://neo4j.com/download-center/ 配置好 JDK 和 Neo4j 的环境变量...

第十一次Javaweb作业

4.登录校验 4.1会话 --用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。 会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求…...

人工智能AI风口已开:如何赋予UI设计与视频剪辑新生命

随着科技的浪潮不断向前推进,人工智能(AI)正以惊人的速度重塑着我们的世界,特别是在创意产业的核心领域——UI设计与视频剪辑中,AI正逐步成为驱动行业创新与变革的关键力量。在这个AI技术全面开花的新时代,…...

计算机专业课面试常见问题-编程语言篇

目录 1. 程序的编译执行流程? 2. C浅拷贝和深拷贝的区别? 3. C虚函数? …...

CSS|05 继承性与优先级

继承性 一、继承性的特点: 1.外层元素身上的样式会被内层元素所继承 2.如果内层元素与外层元素身上的演示相同时,外层元素的样式会被内层元素所覆盖 二、关于继承性的问题 是不是所有样式都能被继承? 答:并不是所有样式能被继承…...

KVM性能优化之内存优化(宿主机)

linux系统自带了一技术叫透明巨型页(transparent huge page),它允许所有的空余内存被用作缓存以提高性能,而且这个设置是默认开启的,我们不需要手动去操作。 Centos下,我们用cat /sys/kernel/mm/transpare…...

【Linux杂货铺】Linux学习之路:期末总结篇1

第一章 什么是Linux? Linux 是 UNIX 操作系统的一个克隆;它由林纳斯 本纳第克特 托瓦兹从零开始编写,并在网络上众多松散的黑客团队的帮助下得以发展和完善;它遵从可移植操作系统接口(POSIX)标准和单一 UNIX 规范…...

GPT-5的到来:智能飞跃与未来畅想

IT之家6月22日消息,在美国达特茅斯工程学院的采访中,OpenAI首席技术官米拉穆拉蒂确认了GPT-5的发布计划,预计将在一年半后推出。穆拉蒂形象地将GPT-4到GPT-5的飞跃比作高中生到博士生的成长。这一飞跃将给我们带来哪些变化?GPT-5的…...

gin中间件

在web应用服务中,完整的业务处理在技术上包含客户端操作,服务端处理,返回处理结果给客户端三个步骤。但是在在更负责的业务和需求场景。一个完整的系统可能要包含鉴权认证,权限管理,安全检查,日志记录等多维…...

swagger常用注解

最近查看接口文档的时候发现,POST方法中的query没法在swagger中显示,查了才发现这是因为Swagger或OpenAPI规范默认将HTTP POST请求的参数识别为请求体(body)参数,而不是查询字符串(query)参数。…...

【Flink metric(1)】Flink指标系统的系统性知识:获取metric以及注册自己的metric

文章目录 一. Registering metrics:向flink注册新自己的metrics1. 注册metrics2. Metric types:指标类型2.1. Counter2.2. Gauge2.3. Histogram(ing)2.4. Meter 二. Scope:指标作用域1. User Scope2. System Scope ing3. User Variables 三. Reporter ing四. System…...

命令模式(Command Pattern)

命令模式(Command Pattern) 定义 命令模式是对命令的封装,每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。 命令模式解耦了请求方和接收方,请求…...

掌握Symfony的模板继承:构建强大且灵活的Web界面

掌握Symfony的模板继承:构建强大且灵活的Web界面 在Symfony框架中,模板继承是一个强大的功能,它允许开发者创建可重用的布局模板,并通过扩展这些模板来构建具体的页面。这种机制不仅提高了代码的可维护性,还使得页面结…...

uboot基本使用网络命令和从服务器端下载linux内核启动

网络命令ip地址设置: setenv gmac_debug 0; setenv mdio_intf rgmii; setenv bootdelay 1; setenv ethaddr 00:xxxx:81:70; // mac地址 setenv ipaddr xxx; //开发板 IP 地址 setenv netmask 255.255.255.0; setenv gatewayip xxx.1; setenv serverip xxxx; //服…...

解决ArcGIS导出的svg格式的图片插入Word后的字体问题

背景 在ArcGIS中设置字体为Times New Roman,但导入Word后字体转为等线。 ArcGIS中的Layout 导入Word​​​​​​ 原因分析 Word无法识别嵌入进SVG格式文件中的字体。 解决方案 在Export Layer窗口中,将Embed fonts取消勾选,Convert cha…...

如何确保 Puppet 配置在复杂网络环境中的可靠分发和同步?

在复杂网络环境中确保 Puppet 配置的可靠分发和同步可以采取以下措施: 网络拓扑规划:在复杂网络环境中,首先需要进行网络拓扑规划,确保网络结构合理,并能够支持可靠的分发和同步机制。 Puppet Master 多节点部署&…...

2024最新!将mysql的数据导入到Solr

Solr导入mysql的数据 如何安装导入数据前准备配置Solr的Jar包以及Mysql驱动包1.1、将solr-8.11.3\dist下的两个包进行移动1.2、将mysql-connect包也移动到该位置1.3、重启Solr项目 配置xml2.1、第一步我们需要创建核心2.2、第二步修改xml(这里是结合19年的教程)2.3、 创建data-…...

Python数据分析第二课:conda的基础命令

Python数据分析第二课:conda的基础命令 1.conda是什么? conda是一个开源的包管理系统,可以帮助我们进行管理多个不同版本的软件包,还可以帮助我们建立虚拟环境,以便对不同的项目进行隔离。 简单来说,conda是一个软…...

微信小程序之bind和catch

这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...