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

这篇具有很好参考价值的文章主要介绍了【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

失真

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

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

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

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

Pillow的实现

创建一张空图写文字:
【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪
旋转了-30度:
【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪
将RGBA图像paste到大图中。
【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪

Python代码:

from PIL import Image, ImageDraw, ImageFont


def 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.size
    return 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 = -30

rotated_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 math

import cv2
import numpy as np

def 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) - cX
    M[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.0
    if 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)

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

旋转文字并贴图

import math

import cv2
import numpy as np


def 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) - cX
    M[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.0
    if 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_SIMPLEX
    thickness = 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_image2

    cv2.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_text
    return 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 = -30

rotated_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)

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

贴图:
【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪文章来源地址https://www.toymoban.com/news/detail-504707.html

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);
        // 透视变换到imgOutTmp
        cv::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部分改色

到了这里,关于【Opencv】PIL Opencv 向图片写入文字并旋转文字,Opencv图片旋转不截断,Opencv图片旋转不裁剪的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包