OpenCV基础:用Python生成一幅黑白图像

这篇博客介绍如何利用Python和OpenCV生成16x16像素的黑白图像,图像左侧为黑色,右侧为白色。通过理解矩阵操作,演示了具体的代码实现,并展示了输出的矩阵和图像。同时,提到了相关博文资源,包括《OpenCV轻松入门》和《计算机视觉40例》两本书,供读者深入学习。

OpenCV的基础是处理图像,而图像的基础是矩阵。
因此,如何使用好矩阵时非常关键的。
下面我们通过一个具体的实例来展示如何通过Python和OpenCV对矩阵进行操作,从而更好地实现对图像的处理。
具体要求:
使用Python:生成一幅左黑右白的灰度图像,图像大小为16×16像素。借助OpenCV库。输出数值,并显示图像。

Python代码

下面的程序通过OpenCV、numpy两个库实现构造矩阵,修改特征值,从而构造一个左侧是黑色、右侧是白色的图像。

Python实现代码如下所示:

# -*- coding: utf-8 -*-
"""
Created on Wed Feb 14 21:45:45 2024

@author: 李立宗

公众号:计算机视觉之光

知识星球:计算机视觉之光

"""

import cv2
import numpy as np

# 创建空白图像,尺寸为16x16
image 
<think> 根据用户需求,需要编写一个Python程序,使用OpenCV库实现以下功能: 1. 导入彩色图像 2. 在窗口显示彩色图像 3. 当用户单击鼠标左键时,将彩色图像转换为灰度图并显示 4. 再次单击鼠标左键时,将灰度图转换为黑白图(二值图像)并显示 5. 可以循环点击切换(但根据描述,只需要两次点击:第一次转灰度,第二次转黑白) 注意:用户连续点击两次,第一次转灰度,第二次转黑白。之后如果再点击,我们可以设计为重置为彩色,或者不做处理。但根据需求,只需要两次转换。为了循环效果,我们可以设计为:彩色->灰度->黑白->彩色... 循环切换。 但是用户明确要求: 第一次左键点击:彩色转灰度 第二次左键点击:灰度转黑白 因此,我们可以设置一个状态变量,记录当前显示的图像状态,然后根据点击次数改变状态并显示相应的图像。 步骤: 1. 使用OpenCV读取彩色图像(注意:OpenCV读取的图像是BGR格式,但显示彩色图像时,我们可以直接使用;转换为灰度图时,使用cv2.COLOR_BGR2GRAY) 2. 创建一个窗口,设置鼠标回调函数 3. 在回调函数中,根据点击次数(或状态)切换图像 4. 初始状态:显示彩色图像 第一次点击:显示灰度图像 第二次点击:显示黑白图像(二值图像,需要设定阈值) 第三次点击:可以回到彩色,或者停止。这里按照需求,我们可以循环切换(三次后回到彩色,四次灰度,五次黑白...) 阈值设定:黑白图像需要设定一个阈值,我们可以使用固定阈值(如128)或者Otsu's二值化(自动阈值)。这里为了简单,使用固定阈值。 状态设计: state = 0: 初始彩色 state = 1: 灰度 state = 2: 黑白 然后每次点击state递增,然后对3取模(0,1,2循环) 另外,注意:在显示图像时,每次点击后需要更新窗口中的图像。 由于OpenCV的窗口回调函数需要特定的参数,我们使用全局变量来记录状态和存储图像(注意:全局变量在多线程中可能有问题,但这里简单示例)。 代码结构: - 读取图像(彩色) - 创建全局变量:state(状态)、原始彩色图像、灰度图像黑白图像(可以在回调函数中按需生成,也可以提前生成好) - 定义鼠标回调函数:当事件为左键按下时,state = (state+1) % 3,然后根据state显示不同的图像 - 显示彩色图像(初始状态) 注意:黑白图像是二值图像,只有0和255两个值。使用cv2.threshold函数生成。 另外,在回调函数中,我们不需要每次都重新计算灰度图像(因为灰度图像在第一次点击后就已经生成,后续可以复用),所以我们可以提前计算好灰度图像,但黑白图像需要根据灰度图像计算,所以可以在第一次点击时生成灰度图像,在第二次点击时再生成黑白图像。或者我们可以在每次切换时根据当前状态生成下一个状态的图像。 为了简化,我们可以: 在初始时,先计算好灰度图像(这样每次点击后切换状态时可以直接使用) 黑白图像也提前计算好(但是黑白图像依赖于灰度图像和阈值,阈值固定,所以也可以提前计算好) 这样,我们只需要在初始时: color_image = 读取的彩色图像 gray_image = cv2.cvtColor(color_image, cv2.COLOR_BGR2GRAY) # 黑白图像: 二值化 _, binary_image = cv2.threshold(gray_image, 128, 255, cv2.THRESH_BINARY) 然后根据状态切换显示: state=0: 显示color_image(注意:color_image是彩色的,而gray_image和binary_image是单通道的,显示单通道图像时,OpenCV会当作灰度图像显示,所以二值图像也会以灰度形式显示(只有黑白两色)) state=1: 显示gray_image state=2: 显示binary_image 但是注意:在显示单通道图像(灰度或二值)时,如果直接用imshow,它会显示为灰度(即黑白图像也是灰度的,但实际只有两个值,看起来就是黑白)。这符合要求。 另一种做法:在回调函数中实时转换,这样可以节省内存(但每次点击都要计算),但考虑到图像不大,也可以。 我们采用提前计算好三种图像的方式。 另外,注意:我们每次切换状态时,需要重新显示图像。所以,在回调函数中,我们改变state,然后根据state选择图像,再调用imshow。 考虑到回调函数中需要访问这些图像,所以将它们设为全局变量。 代码步骤: 1. 导入库:cv2, numpy 2. 定义全局变量:state, color_img, gray_img, binary_img 3. 定义鼠标回调函数:mouse_callback 4. 主函数: 读取图像 计算灰度图像和二值图像 创建窗口,绑定回调函数 初始化state=0,显示彩色图像 等待按键,按ESC退出 回调函数mouse_callback: 事件为左键按下(cv2.EVENT_LBUTTONDOWN)时,state = (state+1) % 3 然后根据state的值,在窗口中显示对应的图像 注意:显示图像使用cv2.imshow,窗口名称要一致。 另外,二值图像是单通道的,而彩色图像是三通道的,它们在显示时OpenCV都会处理(单通道显示为灰度,三通道显示为彩色)。 编写代码: </think> 以下是使用PythonOpenCV实现的程序,实现彩色图像→灰度图像黑白图像的鼠标点击转换功能: ```python import cv2 import numpy as np # 全局状态变量 state = 0 # 0:彩色, 1:灰度, 2:黑白 window_name = "Image Converter" def mouse_callback(event, x, y, flags, param): global state, img_color, img_gray, img_binary # 左键单击事件处理 if event == cv2.EVENT_LBUTTONDOWN: state = (state + 1) % 3 # 状态循环切换 # 根据状态更新显示 if state == 0: cv2.imshow(window_name, img_color) print("当前状态: 彩色图像") elif state == 1: cv2.imshow(window_name, img_gray) print("当前状态: 灰度图像") elif state == 2: cv2.imshow(window_name, img_binary) print("当前状态: 黑白图像") if __name__ == "__main__": # 读取彩色图像 img_color = cv2.imread("input.jpg") # 替换为你的图像路径 if img_color is None: print("错误: 无法加载图像,请检查路径") exit() # 转换为灰度图像 img_gray = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY) # 转换为黑白图像(使用Otsu's二值化) _, img_binary = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 创建窗口并设置鼠标回调 cv2.namedWindow(window_name) cv2.setMouseCallback(window_name, mouse_callback) # 初始显示彩色图像 cv2.imshow(window_name, img_color) print("初始状态: 彩色图像 | 左键单击切换状态") # 等待按键退出 while True: key = cv2.waitKey(1) & 0xFF if key == 27: # ESC键退出 break cv2.destroyAllWindows() ``` ### 程序功能说明: 1. **初始状态**:显示原始彩色图像 2. **第一次左键单击**:转换为灰度图像(单通道) 3. **第二次左键单击**:转换为黑白图像(二值图像) 4. **后续单击**:在三种状态间循环切换 5. **退出方式**:按ESC键退出程序 ### 技术实现细节: 1. **图像转换方法**: - 灰度转换:`cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)`[^1] - 黑白转换:Otsu's自适应阈值法`cv2.threshold()`[^2] 2. **鼠标交互**: - 使用`cv2.setMouseCallback()`注册鼠标事件 - 通过状态机(state变量)管理图像显示状态 3. **图像处理流程**: ```mermaid graph LR A[加载彩色图像] --> B[预计算灰度图像] B --> C[预计算黑白图像] D[鼠标左键单击] --> E{状态判断} E -->|state=0| F[显示彩色图] E -->|state=1| G[显示灰度图] E -->|state=2| H[显示黑白图] ``` ### 使用说明: 1. 安装依赖库: ```bash pip install opencv-python numpy ``` 2. 将代码中的`"input.jpg"`替换为实际图像路径 3. 运行程序后: - 左键单击图像区域切换状态 - 控制台显示当前状态提示 - ESC键退出程序 > **注意**:黑白转换采用Otsu's方法自动计算最佳阈值[^2],如需调整阈值可修改`cv2.threshold()`参数。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superdont

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值