【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪

文章目录

  • 失真
  • Pillow的实现
  • Opencv的实现
    • 不裁剪的旋转图像
    • 旋转文字并贴图
    • C++的图片透视变换

失真

刚性变换: 只有物体的位置(平移变换)和朝向(旋转变换)发生改变,而形状不变,得到的变换称为刚性变换。刚性变换是最一般的变换。

使用透视变换,文字会扭曲失真。刚性变换就不会。

一些介绍: https://blog.csdn.net/liuweiyuxiang/article/details/86510191

在这里插入图片描述

Pillow的实现

创建一张空图写文字:
在这里插入图片描述
旋转了-30度:
在这里插入图片描述
将RGBA图像paste到大图中。
在这里插入图片描述

Python代码:

from PIL import Image, ImageDraw, ImageFontdef draw_text_with_rotation(image, position, text, font_size, color, angle):draw = ImageDraw.Draw(image)font = ImageFont.truetype("STKAITI.TTF", font_size)width, height = draw.textsize(text, font=font)rotated_text = Image.new("RGBA", (width, height), (0, 0, 0, 0))text_draw = ImageDraw.Draw(rotated_text)text_draw.text((0, 0), text, font=font, fill=color)rotated_text.save("rotated_text1.png")rotated_text = rotated_text.rotate(-angle, resample=Image.BICUBIC, expand=True)rotated_text.save("rotated_text2.png")image.paste(rotated_text, position, rotated_text)rotated_text_width, rotated_text_height = rotated_text.sizereturn rotated_text_width, rotated_text_height# 创建一个空白图像
width, height = 800, 600
background_color = (255, 255, 255)  # 白色
image = Image.new("RGB", (width, height), background_color)# 在大图中写入文本并旋转
text = "Hello, World!是吗可以的呀"
text_position = (200, 200)
text_font_size = 30
text_color = (0, 0, 0)  # 黑色
rotation_angle = -30rotated_text_width, rotated_text_height = draw_text_with_rotation(image, text_position, text, text_font_size,text_color, rotation_angle)
# 画一个红色框框选上文字区域
draw = ImageDraw.Draw(image)
draw.rectangle((text_position[0], text_position[1], text_position[0] + rotated_text_width,text_position[1] + rotated_text_height), outline=(255, 0, 0))
# 保存图片
image.save("rotated_text3.png")

Opencv的实现

不裁剪的旋转图像

参考imutils得到:

import mathimport cv2
import numpy as npdef rotate_bound2(image, angle):# grab the dimensions of the image and then determine the center# 抓取图像的尺寸,然后确定中心(h, w) = image.shape[:2](cX, cY) = (w / 2, h / 2)# grab the rotation matrix (applying the negative of the angle to rotate clockwise), then grab the sine and cosine (i.e., the rotation components of the matrix)# 抓取旋转矩阵(应用角度的负数顺时针旋转),然后抓取正弦和余弦(即矩阵的旋转分量)M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)cos = np.abs(M[0, 0])sin = np.abs(M[0, 1])# compute the new bounding dimensions of the image# 计算图像的新边界尺寸nW = int((h * sin) + (w * cos))nH = int((h * cos) + (w * sin))# adjust the rotation matrix to take into account translation# 调整旋转矩阵以考虑平移M[0, 2] += (nW / 2) - cXM[1, 2] += (nH / 2) - cY# perform the actual rotation and return the image# 执行实际旋转并返回图像return cv2.warpAffine(image, M, (nW, nH), flags=cv2.INTER_CUBIC)def rotate_image(image, angle):angle = angle % 360.0if angle == 0:return image.copy()if angle == 180:return cv2.rotate(image, cv2.ROTATE_180)if angle == 90:return cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)if angle == 270:return cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)return rotate_bound2(image, angle)# 读取RGBA
image = cv2.imread('rotated_text1.png', cv2.IMREAD_UNCHANGED)# 对图像进行旋转并扩展
rotated_image = rotate_image(image, 45)# SAVE
cv2.imwrite("rotated_text1_rotated.png", rotated_image)

在这里插入图片描述

旋转文字并贴图

import mathimport cv2
import numpy as npdef rotate_bound2(image, angle):# grab the dimensions of the image and then determine the center# 抓取图像的尺寸,然后确定中心(h, w) = image.shape[:2](cX, cY) = (w / 2, h / 2)# grab the rotation matrix (applying the negative of the angle to rotate clockwise), then grab the sine and cosine (i.e., the rotation components of the matrix)# 抓取旋转矩阵(应用角度的负数顺时针旋转),然后抓取正弦和余弦(即矩阵的旋转分量)M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)cos = np.abs(M[0, 0])sin = np.abs(M[0, 1])# compute the new bounding dimensions of the image# 计算图像的新边界尺寸nW = int((h * sin) + (w * cos))nH = int((h * cos) + (w * sin))# adjust the rotation matrix to take into account translation# 调整旋转矩阵以考虑平移M[0, 2] += (nW / 2) - cXM[1, 2] += (nH / 2) - cY# perform the actual rotation and return the image# 执行实际旋转并返回图像return cv2.warpAffine(image, M, (nW, nH), flags=cv2.INTER_CUBIC)def rotate_image(image, angle):angle = angle % 360.0if angle == 0:return image.copy()if angle == 180:return cv2.rotate(image, cv2.ROTATE_180)if angle == 90:return cv2.rotate(image, cv2.ROTATE_90_CLOCKWISE)if angle == 270:return cv2.rotate(image, cv2.ROTATE_90_COUNTERCLOCKWISE)return rotate_bound2(image, angle)def draw_text_with_rotation(image, position, text, font_size, color, angle):# 定义字体样式font = cv2.FONT_HERSHEY_SIMPLEXthickness = 2# 获取文字的宽度和高度text_size, baseline = cv2.getTextSize(text, font, font_size, thickness)print(text_size, baseline)text_width, text_height = text_size# 灰度图上白纸黑字text_image = np.zeros((text_height + baseline, text_width, 1), np.uint8)cv2.putText(text_image, text, (0, text_height), font, font_size, (255,), thickness)  # top-left corner.# 灰度图给到透明通道上text_image2 = np.zeros((text_height + baseline, text_width, 4), np.uint8)text_image2[:, :, 3] = text_image[:, :, 0]text_image = text_image2cv2.imwrite("self1.png", text_image)rotated_text = rotate_image(text_image, angle)cv2.imwrite("self2.png", rotated_text)rotated_text_height, rotated_text_width = rotated_text.shape[:2]image[position[0]:position[0] + rotated_text_height, position[1]:position[1] + rotated_text_width] = rotated_textreturn rotated_text_width, rotated_text_height# 创建一个空白图像
width, height = 800, 600
image = np.zeros((height, width, 4), np.uint8)# 在大图中写入文本并旋转
text = "Hello, World"
text_position = (200, 200)
text_font_size = 1
text_color = (255, 255, 255)  # 黑色
rotation_angle = -30rotated_text_width, rotated_text_height = draw_text_with_rotation(image, text_position, text, text_font_size,text_color, rotation_angle)
# 画一个红色框框选上文字区域
cv2.rectangle(image, (text_position[0], text_position[1]),(text_position[0] + rotated_text_width, text_position[1] + rotated_text_height), (0, 0, 255, 255), 2)
# 保存图片
cv2.imwrite("self3.png", image)

文字图:
在这里插入图片描述
旋转后:
在这里插入图片描述

贴图:
在这里插入图片描述

C++的图片透视变换

        // textImgMask的四个顶点std::vector<cv::Point> ptsSrc;ptsSrc.emplace_back(0, 0);ptsSrc.emplace_back(textImgMask.cols, 0);ptsSrc.emplace_back(textImgMask.cols, textImgMask.rows);ptsSrc.emplace_back(0, textImgMask.rows);// ptsImgText的四个顶点std::vector<cv::Point> ptsDst;ptsDst.emplace_back(ptsImgText[0]);ptsDst.emplace_back(ptsImgText[1]);ptsDst.emplace_back(ptsImgText[2]);ptsDst.emplace_back(ptsImgText[3]);// 计算透视变换矩阵cv::Mat homography = cv::findHomography(ptsSrc, ptsDst);// 透视变换到imgOutTmpcv::Mat imgOutTmp = cv::Mat::zeros(img.size(), CV_8UC3);cv::warpPerspective(textImgMask, imgOutTmp, homography, img.size());// 转到原图cv::Mat gray;cv::cvtColor(imgOutTmp, gray, cv::COLOR_BGR2GRAY);imgOut.setTo(cv::Scalar(textColors[i][2], textColors[i][1], textColors[i][0]), gray > 125);  // mask部分改色

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

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

相关文章

基于matlab多运动目标跟踪监测算法实现(附源码)

一、前言 此示例演示如何对来自固定摄像机的视频中的移动对象执行自动检测和基于运动的跟踪。 二、介绍 移动物体检测和基于运动的跟踪是许多计算机视觉应用的重要组成部分&#xff0c;包括活动识别、交通监控和汽车安全。基于运动的对象跟踪问题可以分为两部分&#xff1a; 检…

【人工智能与机器学习】决策树ID3及其python实现

文章目录 1 决策树算法1.1 特征选择1.2 熵&#xff08;entropy&#xff09;1.3 信息增益 2 ID3算法的python实现总结 1 决策树算法 决策树&#xff08;Decision Tree)是一类常见的机器学习方法&#xff0c;是一种非常常用的分类方法&#xff0c;它是一种监督学习。常见的决策树…

ChatGPT实战:高考志愿填报

近期&#xff0c;随着各地陆续发布高考成绩&#xff0c;高考志愿填报市场随之升温&#xff0c;“高报师”再次成为“香饽饽”。填报志愿对中学生来说太难&#xff0c;在一个懵懂的年纪做这样一个决策&#xff0c;份量是比较重的。当普通人没很多的信息做参考的时候&#xff0c;…

LeetCode 剑指 Offer 13. 机器人的运动范围(深度遍历)

LeetCode 剑指 Offer 13. 机器人的运动范围 原题思路代码运行截图收获 原题 LeetCode 剑指 Offer 13. 机器人的运动范围 思路 通过深度遍历来找出所有可达的格子通过0、1、2来区分未遍历、可到达、不可到达三种状态 代码 class Solution { public:int visited[109][109];i…

python中使用OAK-D PRO相机实现OCR功能

目录 OAK简介Tesseract简介Tesseract OCR安装包安装 Tesseract OCR 代码实现 OAK简介 OAK&#xff08;OpenCV AI Kit&#xff09;是一个开源的智能视觉平台&#xff0c;它集成了硬件和软件组件&#xff0c;旨在提供高性能的实时目标检测、识别和跟踪等视觉AI功能。OAK由Luxoni…

【机器学习】信息熵和信息度量

一、说明 信息熵是概率论在信息论的应用,它简洁完整,比统计方法更具有计算优势。在机器学习中经常用到信息熵概念,比如决策树、逻辑回归、EM算法等。本文初略介绍一个皮毛,更多细节等展开继续讨论。 二、关于信息熵的概念 2.1 要素描述 信息熵:熵是一种测量随机变量 X …

CVE-2023-34541 LangChain 任意命令执行

漏洞简介 LangChain是一个用于开发由语言模型驱动的应用程序的框架。 在LangChain受影响版本中&#xff0c;由于load_prompt函数加载提示文件时未对加载内容进行安全过滤&#xff0c;攻击者可通过构造包含恶意命令的提示文件&#xff0c;诱导用户加载该文件&#xff0c;即可造…

C# csc构建dll 和 csc构建时指定dll

新建一个mydll.cs&#xff1b; using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace myDLL {public class MyMath{public int add(int x, int y){return x y;}public int sub(int x, int y){return x - y;}} } 用下图命令构建…

爬虫---某翻译响应解密和sign逆向

目标网址接口&#xff1a;aHR0cHM6Ly9kaWN0LnlvdWRhby5jb20vd2VidHJhbnNsYXRl 仅供学习交流使用&#xff0c;非商业用途&#xff0c;如有侵权&#xff0c;请联系删除!!!仅供学习交流使用&#xff0c;非商业用途&#xff0c;如有侵权&#xff0c;请联系删除!!!仅供学习交流使用&…

【Linux】—— 进程的环境变量

序言&#xff1a; 在上期我们已经对进程PCB以及进程状态进行了详细的解释说明。今天&#xff0c;我将带领大家学习的是关于进程的环境变量的问题。 目录 &#xff08;一&#xff09;孤儿进程 1、基本介绍 2、代码演示 &#xff08;二&#xff09;环境变量 1、基本概念 2…

RedmiBook Pro 15S AMD Ryzen 7 5800H电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件配置 硬件型号驱动情况 主板RedmiBook Pro 15S 2021 处理器AMD Ryzen™ 7 5800H已驱动 内存16 GB 3200 MHz DDR4已驱动 硬盘Samsung 970EVO 512GB已驱动 显卡HD …

SpringMVC (一) 什么是SpringMVC

一、回顾MVC 1.1、什么是MVC MVC是模型(Model)、视图(View)、控制器(Controller)的简写&#xff0c;是一种软件设计规范。是将业务逻辑、数据、显示分离的方法来组织代码。MVC主要作用是降低了视图与业务逻辑间的双向偶合。MVC不是一种设计模式&#xff0c;MVC是一种架构模式。…