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

OpenCV 04.19 练习

1.

创建一个 PyQt 应用程序,该应用程序能够:
1.使用 OpenCV 加载一张图像。
2.在 PyQt 的窗口中显示这张图像。
3.提供四个按钮(QPushButton):
- 一个用于将图像转换为灰度图
- 一个用于将图像恢复为原始彩色图
- 一个用于将图像进行翻转
- 一个用于将图像进行旋转
4.当用户点击按钮时,相应地更新窗口中显示的图像。
import sys
import cv2from PyQt6.QtWidgets import (QApplication, QWidget, QLabel,QPushButton, QHBoxLayout, QVBoxLayout
)
from PyQt6.QtGui import QPixmap, QImageclass ImageApp(QWidget):def __init__(self, image_path):super().__init__()self.setWindowTitle("OpenCV")# 使用 OpenCV 加载图像self.original_img = cv2.imread(image_path)if self.original_img is None:raise FileNotFoundError(f"未找到图像: {image_path}")# 保存当前显示的图像(初始化为原图)self.current_img = self.original_img.copy()self._init_ui()self._update_image()def _init_ui(self):# 用于显示图像的 QLabelself.image_label = QLabel(self)# 创建按钮btn_gray = QPushButton("灰度化", self)btn_original = QPushButton("原图", self)btn_flip = QPushButton("翻转", self)btn_rotate = QPushButton("旋转", self)# 连接按钮点击事件到相应函数btn_gray.clicked.connect(self.to_gray)btn_original.clicked.connect(self.to_original)btn_flip.clicked.connect(self.flip)btn_rotate.clicked.connect(self.rotate)# 按钮水平布局btn_layout = QHBoxLayout()for btn in (btn_gray, btn_original, btn_flip, btn_rotate):btn_layout.addWidget(btn)# 主布局:先是图像标签,再是按钮布局main_layout = QVBoxLayout()main_layout.addWidget(self.image_label)main_layout.addLayout(btn_layout)self.setLayout(main_layout)def _update_image(self):# 将 OpenCV 的 BGR 图像转换为 QImageimg_rgb = cv2.cvtColor(self.current_img, cv2.COLOR_BGR2RGB)h, w, ch = img_rgb.shapebytes_per_line = ch * wqt_image = QImage(img_rgb.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)pixmap = QPixmap.fromImage(qt_image)# 在 QLabel 中显示 QPixmapself.image_label.setPixmap(pixmap)# 调整窗口大小以适应图像self.resize(pixmap.width(), pixmap.height())def to_gray(self):# 将当前图像转换为灰度图,然后再转为三通道以便显示gray = cv2.cvtColor(self.current_img, cv2.COLOR_BGR2GRAY)self.current_img = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)self._update_image()def to_original(self):# 恢复为加载时的原始彩色图像self.current_img = self.original_img.copy()self._update_image()def flip(self):# 水平翻转图像self.current_img = cv2.flip(self.current_img, 1)self._update_image()def rotate(self):# 顺时针旋转90度self.current_img = cv2.rotate(self.current_img, cv2.ROTATE_90_CLOCKWISE)self._update_image()if __name__ == "__main__":app = QApplication(sys.argv)# 创建并显示应用窗口,参数为图像路径window = ImageApp('../images/lena.png')window.show()sys.exit(app.exec())

2.

创建一个 PyQt 应用程序,该应用程序能够:
1.使用 OpenCV 加载一张彩色图像,并在 PyQt 的窗口中显示它。
2.提供一个滑动条(QSlider),允许用户调整图像的亮度。
3.当用户调整滑动条时,实时更新窗口中显示的图像亮度。
4.添加另一个滑动条(QSlider),允许用户调整图像的对比度。
5.当用户调整滚动条时,实时更新窗口中显示的图像对比度。
6.提供一个按钮(QPushButton),允许用户将图像保存为新的文件。
7.当用户点击保存按钮时,将调整后的图像保存到指定的路径,OpenCV中使用cv2.imwrite()来保存图片。
import sys
import cv2
import numpy as np
from PyQt6.QtWidgets import (QApplication, QWidget, QLabel, QSlider,QPushButton, QFileDialog, QHBoxLayout, QVBoxLayout
)
from PyQt6.QtGui import QPixmap, QImage
from PyQt6.QtCore import Qtclass ImageEditor(QWidget):def __init__(self, image_path):super().__init__()self.setWindowTitle("亮度与对比度调节应用")# 使用 OpenCV 加载彩色图像self.original_img = cv2.imread(image_path)if self.original_img is None:raise FileNotFoundError(f"未找到图像: {image_path}")# 保存为 float32 方便缩放计算self.img_float = self.original_img.astype(np.float32)# 当前显示图像self.current_img = self.original_img.copy()self._init_ui()self.update_image()def _init_ui(self):# 图像显示标签self.image_label = QLabel(self)# 亮度滑动条 (beta)self.brightness_slider = QSlider(Qt.Orientation.Horizontal)self.brightness_slider.setRange(-100, 100)self.brightness_slider.setValue(0)self.brightness_slider.setTickInterval(10)self.brightness_slider.valueChanged.connect(self.update_image)# 对比度滑动条 (alpha)self.contrast_slider = QSlider(Qt.Orientation.Horizontal)self.contrast_slider.setRange(0, 300)self.contrast_slider.setValue(100)self.contrast_slider.setTickInterval(10)self.contrast_slider.valueChanged.connect(self.update_image)# 保存按钮self.save_button = QPushButton("保存图像")self.save_button.clicked.connect(self.save_image)# 布局slider_layout = QVBoxLayout()slider_layout.addWidget(QLabel("亮度调节 (beta):"))slider_layout.addWidget(self.brightness_slider)slider_layout.addWidget(QLabel("对比度调节 (alpha x100):"))slider_layout.addWidget(self.contrast_slider)btn_layout = QHBoxLayout()btn_layout.addLayout(slider_layout)btn_layout.addWidget(self.save_button)main_layout = QVBoxLayout()main_layout.addWidget(self.image_label)main_layout.addLayout(btn_layout)self.setLayout(main_layout)def update_image(self):# 从滑动条获取参数beta = self.brightness_slider.value()           # 亮度偏移alpha = self.contrast_slider.value() / 100.0    # 对比度系数# g(i,j) = alpha * f(i,j) + betaadjusted = cv2.convertScaleAbs(self.img_float, alpha=alpha, beta=beta)self.current_img = adjusted# 转换并显示img_rgb = cv2.cvtColor(self.current_img, cv2.COLOR_BGR2RGB)h, w, ch = img_rgb.shapebytes_per_line = ch * wqt_image = QImage(img_rgb.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)pixmap = QPixmap.fromImage(qt_image)self.image_label.setPixmap(pixmap)self.resize(pixmap.width(), pixmap.height()+100)def save_image(self):# 弹出文件对话框选择保存路径path, _ = QFileDialog.getSaveFileName(self, "保存图像", "adjusted.png", "Images (*.png *.jpg)")if path:cv2.imwrite(path, self.current_img)if __name__ == "__main__":app = QApplication(sys.argv)# 创建并显示窗口, 参数为图像路径window = ImageEditor('../images/lena.png')window.show()sys.exit(app.exec())

3.

创建一个 PyQt 应用程序,该应用程序能够:
1.使用 OpenCV 加载一张图像。
2.在 PyQt 的窗口中显示这张图像。
3.提供一个下拉列表(QComboBox),对图像做(模糊、锐化、边缘检测)处理:
- 模糊——使用cv2.GaussianBlur()实现
- 锐化——使用cv2.Laplacian()、cv2.Sobel()实现
- 边缘检测——使用cv2.Canny()实现
4.当用户点击下拉列表选项时,相应地更新窗口中显示的图像。
5.提供一个按钮,当用户点击按钮时,能保存调整后的图像。
import sys
import cv2
import numpy as np
from PyQt6.QtWidgets import (QApplication, QWidget, QLabel, QComboBox,QPushButton, QFileDialog, QHBoxLayout, QVBoxLayout
)
from PyQt6.QtGui import QPixmap, QImageclass ImageApp(QWidget):def __init__(self, image_path):super().__init__()self.setWindowTitle("图像处理应用")# 1. 使用 OpenCV 加载图像self.original_img = cv2.imread(image_path)if self.original_img is None:raise FileNotFoundError(f"未找到图像: {image_path}")self.current_img = self.original_img.copy()# 初始化界面self._init_ui()self._update_image()def _init_ui(self):# QLabel 用于显示图像self.image_label = QLabel(self)# 3. 下拉列表:模糊、锐化、边缘检测self.combo = QComboBox(self)self.combo.addItems(["原图", "模糊", "锐化", "边缘检测"])self.combo.currentTextChanged.connect(self.process_image)# 7. 保存按钮self.save_btn = QPushButton("保存图像", self)self.save_btn.clicked.connect(self.save_image)# 布局ctrl_layout = QHBoxLayout()ctrl_layout.addWidget(self.combo)ctrl_layout.addWidget(self.save_btn)main_layout = QVBoxLayout()main_layout.addWidget(self.image_label)main_layout.addLayout(ctrl_layout)self.setLayout(main_layout)def _update_image(self):# 将 OpenCV BGR 图像转为 RGB 并显示img_rgb = cv2.cvtColor(self.current_img, cv2.COLOR_BGR2RGB)h, w, ch = img_rgb.shapebytes_per_line = ch * wqt_image = QImage(img_rgb.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)pixmap = QPixmap.fromImage(qt_image)self.image_label.setPixmap(pixmap)# 调整窗口大小self.resize(pixmap.width(), pixmap.height() + 50)def process_image(self, mode: str):# 处理图像并更新显示if mode == "原图":self.current_img = self.original_img.copy()elif mode == "模糊":# GaussianBlurself.current_img = cv2.GaussianBlur(self.original_img, (5, 5), 0)elif mode == "锐化":# Laplacian + Sobelgray = cv2.cvtColor(self.original_img, cv2.COLOR_BGR2GRAY)lap = cv2.Laplacian(gray, cv2.CV_64F)sobx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)soby = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)edges_lap = cv2.convertScaleAbs(lap)edges_sob = cv2.convertScaleAbs(np.abs(sobx) + np.abs(soby))merged = cv2.addWeighted(edges_lap, 0.5, edges_sob, 0.5, 0)sharp_gray = cv2.add(gray, merged)sharp_gray = np.clip(sharp_gray, 0, 255).astype(np.uint8)self.current_img = cv2.cvtColor(sharp_gray, cv2.COLOR_GRAY2BGR)elif mode == "边缘检测":gray = cv2.cvtColor(self.original_img, cv2.COLOR_BGR2GRAY)edges = cv2.Canny(gray, 100, 200)self.current_img = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)self._update_image()def save_image(self):# 弹出对话框,保存当前图像path, _ = QFileDialog.getSaveFileName(self, "保存图像", "processed.png", "Images (*.png *.jpg)")if path:cv2.imwrite(path, self.current_img)if __name__ == "__main__":app = QApplication(sys.argv)# 创建并显示窗口, 参数为图像路径window = ImageApp('../images/card.png')window.show()sys.exit(app.exec())

4

请编写一段Python代码,实现以下功能:

  1. 读取一张二维码图片
  2. 进行二值化处理和形态学操作,获取二维码轮廓
  3. 通过轮廓外接特征检测或者多边形逼近等获取 二维码的四个点
  4. 进行透视变换,矫正二维码图像
import cv2
import numpy as npimg = cv2.imread('../images/qrcode.png')
# 灰度化
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化
ret, thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 高斯滤波
img_gaussian = cv2.GaussianBlur(thresh, (5, 5), 7)
# 腐蚀膨胀
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (11, 11))
eroded = cv2.erode(img_gaussian, kernel, iterations=1)
morphed = cv2.dilate(eroded, kernel, iterations=2)# 检测轮廓
contours, _ = cv2.findContours(morphed, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)# 给contours排序,按面积从大到小排序, 取最大轮廓
cnt = sorted(contours, key=cv2.contourArea, reverse=True)[0]
# 对最大轮廓做逼近
perimeter = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, perimeter * 0.04, True)
# 画出轮廓
cv2.drawContours(img, [approx], -1, (0, 0, 255), 1)# 进行矫正
src = np.float32(approx).reshape(-1, 2)
x = src[:, 0]
y = src[:, 1]
dst = np.float32([[min(x), min(y)],[min(x), max(y)],[max(x), max(y)],[max(x), min(y)]])
M = cv2.getPerspectiveTransform(src, dst)
# 透视变换
img_warpPerspective = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))# 显示图像
cv2.imshow('img', img)
cv2.imshow('warped', img_warpPerspective)
cv2.waitKey(0)

5

请编写一段Python代码,实现以下功能:

  1. 读取一张彩色图像
  2. 制作要提取颜色的掩膜
  3. 输出抠图后的前景图 和 背景图
import cv2
import numpy as np# 1. 读取一张彩色图像
img = cv2.imread('../images/rose.jpg')
if img is None:raise FileNotFoundError("无法加载图像,请检查路径是否正确")# 转到 HSV 空间,便于按色调分割
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 2. 制作“红色花朵”掩膜(前景)
# 红色在 HSV 中分布在两段,需要合并
lower_red1 = np.array([0, 50, 50])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([160, 50, 50])
upper_red2 = np.array([180, 255, 255])
mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
mask_red = cv2.bitwise_or(mask1, mask2)# 3. 输出抠图后的前景图和背景图
# 前景:仅保留红色花朵区域
foreground = cv2.bitwise_and(img, img, mask=mask_red)# 背景:使用掩膜的反掩膜,保留花朵以外的区域
mask_inv = cv2.bitwise_not(mask_red)
background = cv2.bitwise_and(img, img, mask=mask_inv)# 4. 显示结果
cv2.imshow('Original', img)
cv2.imshow('Foreground - Red Flowers', foreground)
cv2.imshow('Background - Rest of Image', background)
cv2.waitKey(0)
cv2.destroyAllWindows()

相关文章:

  • Python带有else子句的循环语句
  • 【漫话机器学习系列】210.标准化(Standardization)
  • docker 大模型
  • Cribl 优化EC2 ip-host-region 数据
  • Grouped Query Attention (GQA) PyTorch实现
  • 关于学习STM32的C语言的知识
  • matlab 处理海洋数据并画图的工具包--ocean_data_tools
  • 基于模板匹配的信用卡号码识别系统
  • 学习笔记十七——Rust 支持面向对象编程吗?
  • system V消息队列和信号量的学习
  • Python番外——常用的包功能讲解和分类组合
  • 服务治理-搭建Nacos注册中心
  • @EnableAsync+@Async源码学习笔记之六
  • 【自动化测试框架】什么是对象层?
  • [密码学基础]密码学常用名词深度解析:从基础概念到实战应用
  • npm 常用操作和配置
  • 国产GPU生态现状评估:从寒武纪到壁仞的编程适配挑战
  • DeepSeek与Napkin:信息可视化领域的创新利器
  • 安徽合肥京东自营代运营如何突围?
  • CSRF 请求伪造Referer 同源置空配合 XSSToken 值校验复用删除
  • 最高法报告点名“夜郎古酒”商标侵权案:促成当事人握手言和
  • “代课老师被男友杀害案”一审开庭,将择期宣判
  • 全球在役最大火电厂被通报
  • “雷公”起诉人贩子王浩文案将开庭:索赔6元,“讨个公道”
  • 复旦大学史地学系在北碚
  • 人民日报头版开新栏:收官之年干劲满,决战决胜勇争先