【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

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

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

相关文章

骨传导耳机哪个牌子值得入手?精选热销榜TOP5推荐!

短短数年,骨传导耳机的市场规模迅速扩大,其受欢迎程度可见一斑。但身为拥有十二年经验的音频专家,我在此有义务提醒大家,在选择骨传导耳机时一定要谨慎。面对市面上的众多品牌,一定不要盲目入手,不然很容易…

leetcode提速小技巧

据我所知,leetcode可能是按最难那个用例给你打分的,非难题的用时好坏不完全看复杂度,因为可能都差不多,O(n/2)和O(n)虽然都是O(n),但是反应到成绩上是不同的,所以,尽可能的在条件足够的情况下提…

Java鲜花下单预约系统源码小程序源码

让美好触手可及 🌸一、开启鲜花新篇章 在繁忙的都市生活中,我们总是渴望那一抹清新与美好。鲜花,作为大自然的馈赠,总能给我们带来无尽的惊喜与愉悦。但你是否曾因为工作繁忙、时间紧张而错过了亲自挑选鲜花的机会?今…

KVB交易平台: 美元兑日元升破161,这一趋势会继续吗?

在2024年6月28日,美元在亚洲交易市场中表现强劲,接近四十年来的新高,预计将连续第二个季度上涨。与此同时,日本日元持续走低,跌至38年以来的新低,首次突破161关口。在东京交易中,日元兑美元贬值…

小程序反编译后报错“_typeof3 is not a function”

详情->本地设置->取消勾选“将JS编译成ES5” 参考链接:https://blog.csdn.net/csl12919/article/details/131569914

Ubuntu网络管理命令:netstat

安装Ubuntu桌面系统(虚拟机)_虚拟机安装ubuntu桌面版-CSDN博客 顾名思义,netstat命令不是用来配置网络的,而是用来查看各种网络信息的,包括网络连接、路由表以及网络接口的各种统计数据等。 netstat命令的基本语法如…

湿气易藏在身体的这3个地方,1个方法“定位祛湿”,摆脱它!

6月的雨,滴滴答答的下了十几天了,体内湿气越来越重,皮肤发痒、身体沉重、四肢乏力、总犯困、还出现了消化不良,甚至腹泻的情况…… 为什么我都在积极喝祛湿汤,却不见效呢? 一个很重要的原因可能是&#xff…

「ETL趋势」FDL数据开发支持版本管理、实时管道支持多对一、数据源新增支持神通

FineDataLink作为一款市场上的顶尖ETL工具,集实时数据同步、ELT/ETL数据处理、数据服务和系统管理于一体的数据集成工具,进行了新的维护迭代。本文把FDL4.1.8最新功能作了介绍,方便大家对比:(产品更新详情:…

企业出海的浪潮下,如何利用亚马逊云(AWS)更好地应对?

在全球化的浪潮下,越来越多的企业开始将目光投向国际市场。在这个数字化时代,云计算技术成为企业出海的必备利器之一。AWS云作为全球领先的云服务提供商,凭借其卓越的性能和完善的服务体系,成为众多企业出海的首选。 一、出海为什…

CDN入门

在腾讯云上使用CDN 1、参考 内容分发网络 CDN 从零开始配置 CDN-快速入门-文档中心-腾讯云 2、验证 访问: 登录 - 腾讯云 Window10本地电脑使用命令验证 nslookup -qt-cname hmblogs.com.cn Ubuntu下验证 dig hmblogs.com.cn

SpringBoot整合Solr进行搜索(简单)

SpringBoot整合Solr进行搜索 创建SpringBoot项目pom中加入Solr依赖配置 Solr创建实体编写一个简单的ID查询打印结果 参考文章 创建SpringBoot项目 这里基于aliyun提供的快速构建一个项目。我们这主要是整合Solr。 pom中加入Solr依赖 maven下载地址 pom中加入以下内容&#x…

「ETL趋势」FDL定时任务区分开发/生产模式、API输入输出支持自定义响应解析

FineDataLink作为一款市场上的顶尖ETL工具,集实时数据同步、ELT/ETL数据处理、数据服务和系统管理于一体的数据集成工具,进行了新的维护迭代。本文把FDL4.1.7最新功能作了介绍,方便大家对比:(产品更新详情:…

鸿蒙开发设备管理:【@ohos.brightness (屏幕亮度)】

屏幕亮度 该模块提供屏幕亮度的设置接口。 说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import brightness from ohos.brightness;brightness.setValue setValue(value: number):…

【ai】ubuntu18.04 找不到 nvcc --version问题

nvcc --version显示command not found问题 这个是cuda 库: windows安装了12.5 : 参考大神:解决nvcc --version显示command not found问题 原文链接:https://blog.csdn.net/Flying_sfeng/article/details/103343813 /usr/local/cuda/lib64 与 /usr/local/cuda-11.3/lib64 完…

数据挖掘常见算法(聚类)

划分方法 K-均值算法(K-means算法) 方法: 首先选择K个随机的点,称为聚类中心.对于数据集中的,每一个数据,按照距离K个中心点的距离,将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一类.计算每一个组的平均值,将改组所关联的中心点移动到平均值的位置重复2~…

《昇思25天学习打卡营第7天 | 昇思MindSpore模型训练》

第七天 之前学习了模型训练的构建数据集,定义神经网络模型。本节学习了定义超参、损失函数及优化器,输入数据集进行训练与评估。 模型训练的步骤 1.构建数据集 2.定义神经网络模型 3.定义超参、损失函数及优化器 4.输入数据集进行训练与评估

关于IDEA启动报错 【JAVA_HOME does not point to a valid JM installation】

希望文章能给到你启发和灵感~ 感谢支持和关注~ 阅读指南 一、基础环境说明1.1 硬件环境1.2 软件环境 二、起因 一、基础环境说明 考虑环境因素不同,大家适当的对比自己的软硬件环境情况分析~ 1.1 硬件环境 MacOS Monterey 版本 1…

海外仓一件代发业务优化指南:成本构成分析及优化策略

一件代发是大部分海外仓的核心业务,不过随着海外仓市场竞争的加剧,仓库经营成本上涨成了普遍现象。 今天我们会结合众多海外仓的实际情况,综合分析海外仓一件代发业务成本的构成,成本激增的原因以及对应的优化策略,希…

SmartEDA电路仿真教学VS传统教学:谁将颠覆未来教育战场?

在科技飞速发展的今天,教育领域也迎来了前所未有的变革。传统的教学方式正面临着在线教学工具的强劲挑战,特别是在电路仿真教学领域,SmartEDA这样的在线工具正逐渐崭露头角。那么,SmartEDA电路仿真教学与传统教学之间,…

没有兴趣爱好的我,怎么填报高考志愿选专业?

这是我从知乎看来的一个问题,也在知乎做了回复,顺便摘录下来做个记录。 原文是:以为考完了就走向人生巅峰了,谁知道会这么down。我爸这两天一直追着问我有什么理想,搞得我很难受。过去的十几年里,我对人生都…