解决opencv读取经过labelImg工具进行标注后的图像出现的框与图像旋转方向不一致的情况?使用看图软件旋转之后查看的确旋转了,但是分辨率没有发生变化。而只是修改了图片的元信息???

图片元信息Exif,给你详细讲讲 - 知乎 (zhihu.com)icon-default.png?t=O83Ahttps://zhuanlan.zhihu.com/p/366726838在使用labelimg等开源的图像标注软件过程中发现,有时候一些图像数据集,比如从手机拍摄的照片可能会有一个图像的方向的选项供选择,拍出来的照片,也因此图像分辨率是会发生变化的。
关于使用opencv读取经过labelImg工具进行标注后的图像出现的框与图像旋转方向不一致的问题 [author: linkrain]_opencv读图与labelimg显示不一致-CSDN博客icon-default.png?t=O83Ahttps://blog.csdn.net/xuan_xuan_/article/details/100295306

利用现有的一些比如WPS图片、360AI图片等等成熟的国产化的图像处理查看软件,是可以直接进行图像的旋转的。

测试发现,有些图像并不能成功修改其分辨率,而是修改了其图片的方向和Exif信息。

遂开发一个PyQT的小工具——名为——图像旋转器,修改图像的方向Exif的同时,修改其分辨率,实现正确地在labelimg软件中实现加载

import sys
import os
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QFileDialog, QVBoxLayout, QWidget
from PyQt5.QtGui import QPixmap, QImage
from PyQt5.QtCore import Qt
from PIL import Image
import cv2
import numpy as np


class ImageRotator(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("图像旋转与调整")
        self.setGeometry(100, 100, 800, 600)

        self.current_image_index = 0
        self.image_paths = []
        self.cv_image = None  # OpenCV 格式的图像
        self.original_size = (0, 0)  # 原始图像的分辨率

        self.initUI()

    def initUI(self):
        # 设置布局
        self.label = QLabel(self)
        self.label.setAlignment(Qt.AlignCenter)

        self.btn_open_folder = QPushButton("打开文件夹", self)
        self.btn_open_folder.clicked.connect(self.open_folder)

        self.btn_prev = QPushButton("上一张", self)
        self.btn_prev.clicked.connect(self.show_previous_image)
        self.btn_prev.setEnabled(False)

        self.btn_next = QPushButton("下一张", self)
        self.btn_next.clicked.connect(self.show_next_image)
        self.btn_next.setEnabled(False)

        self.btn_rotate_left = QPushButton("向左旋转90度", self)
        self.btn_rotate_left.clicked.connect(lambda: self.rotate_image(-90))
        self.btn_rotate_left.setEnabled(False)

        self.btn_rotate_right = QPushButton("向右旋转90度", self)
        self.btn_rotate_right.clicked.connect(lambda: self.rotate_image(90))
        self.btn_rotate_right.setEnabled(False)

        self.btn_save = QPushButton("保存", self)
        self.btn_save.clicked.connect(self.save_image)
        self.btn_save.setEnabled(False)

        layout = QVBoxLayout()
        layout.addWidget(self.btn_open_folder)
        layout.addWidget(self.label)
        layout.addWidget(self.btn_prev)
        layout.addWidget(self.btn_next)
        layout.addWidget(self.btn_rotate_left)
        layout.addWidget(self.btn_rotate_right)
        layout.addWidget(self.btn_save)

        container = QWidget()
        container.setLayout(layout)
        self.setCentralWidget(container)

    def open_folder(self):
        folder_path = QFileDialog.getExistingDirectory(self, "选择图像文件夹")
        if folder_path:
            self.image_paths = [os.path.join(folder_path, f) for f in os.listdir(folder_path)
                                if f.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.tiff'))]
            self.current_image_index = 0
            if self.image_paths:
                self.show_image()
                self.btn_prev.setEnabled(True)
                self.btn_next.setEnabled(True)
                self.btn_rotate_left.setEnabled(True)
                self.btn_rotate_right.setEnabled(True)
                self.btn_save.setEnabled(True)
            else:
                self.label.setText("没有符合条件的图像。")

    def show_image(self):
        image_path = self.image_paths[self.current_image_index]
        # 使用 OpenCV 读取图像,忽略 EXIF 中的方向信息
        self.cv_image = cv2.imread(image_path, cv2.IMREAD_COLOR | cv2.IMREAD_IGNORE_ORIENTATION)
        self.original_size = (self.cv_image.shape[1], self.cv_image.shape[0])  # 获取原始图像分辨率
        self.display_image(self.cv_image)

    def display_image(self, cv_image):
        """在 QLabel 上显示 OpenCV 图像,并在右上角显示分辨率"""
        height, width, channel = cv_image.shape
        # 创建带有分辨率信息的图像副本
        cv_image_with_text = cv_image.copy()

        # 使用 OpenCV 在图像上绘制分辨率
        cv2.putText(cv_image_with_text, f'{width}x{height}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

        # 转换为 QImage 并展示
        bytes_per_line = 3 * width
        q_image = QImage(cv_image_with_text.data, width, height, bytes_per_line, QImage.Format_BGR888)
        pixmap = QPixmap.fromImage(q_image)

        # 将 QPixmap 设置到 QLabel 上
        self.label.setPixmap(pixmap.scaled(self.label.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation))

    def show_previous_image(self):
        if self.current_image_index > 0:
            self.current_image_index -= 1
            self.show_image()

    def show_next_image(self):
        if self.current_image_index < len(self.image_paths) - 1:
            self.current_image_index += 1
            self.show_image()

    def rotate_image(self, angle):
        if self.cv_image is not None:
            # 旋转图像并更新当前图像
            (h, w) = self.cv_image.shape[:2]
            center = (w // 2, h // 2)
            matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
            cos = np.abs(matrix[0, 0])
            sin = np.abs(matrix[0, 1])

            # 计算旋转后的图像大小
            new_w = int((h * sin) + (w * cos))
            new_h = int((h * cos) + (w * sin))

            # 调整旋转矩阵以考虑新尺寸
            matrix[0, 2] += (new_w / 2) - center[0]
            matrix[1, 2] += (new_h / 2) - center[1]

            # 旋转图像
            self.cv_image = cv2.warpAffine(self.cv_image, matrix, (new_w, new_h))
            self.display_image(self.cv_image)

    def save_image(self):
        if self.cv_image is not None:
            save_path = self.image_paths[self.current_image_index]
            # 保存图像,完全忽略 EXIF 信息
            modified_image = Image.fromarray(cv2.cvtColor(self.cv_image, cv2.COLOR_BGR2RGB))
            modified_image.save(save_path, format="JPEG", quality=95)

            modified_size = (self.cv_image.shape[1], self.cv_image.shape[0])  # 获取修改后的图像分辨率
            print(f"图像已保存:{save_path} 原图分辨率:{self.original_size[0]}x{self.original_size[1]} "
                  f"修改后分辨率为:{modified_size[0]}x{modified_size[1]}已保存")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = ImageRotator()
    window.show()
    sys.exit(app.exec_())

pip install pyqt5后直接运行本程序即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

光芒再现dev

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

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

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

打赏作者

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

抵扣说明:

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

余额充值