opencv文字旋转 putText旋转90°

news2024/11/24 22:34:37

文章目录

  • ● opencv文字旋转 putText旋转90°
  • 1. cv::getTextSize获取文字的尺寸textSize
  • 2. 设置文字图像textImg尺寸格式
  • 3. 将文字绘制在文字图像textImg上
  • 4. 对文字图像textImg进行旋转
  • 5. 在原图img上设置用来放置文字图像textImg的roi区域
    • 5.1 矩形区域roi
    • 5.2 行列范围roi
  • 6. 将文字图像textImg放置在roi区域上
    • 6.1 copyTo
      • 6.1.1 不设置掩膜
      • 6.2.2 设置掩膜
    • 6.2 `+` / `add()`
  • 7. 整体流程代码

● opencv文字旋转 putText旋转90°

  • putText本身不支持对文字进行旋转,所以将文字写在图像上,将图像进行旋转后再贴到原如上(可设置掩膜),以实现文字旋转的效果

1. cv::getTextSize获取文字的尺寸textSize

std::string text="treeAndCat";
int fontFace=cv::FONT_HERSHEY_SIMPLEX;//字体
double fontScale=2;//缩放系数
cv::Scalar color=cv::Scalar(255,255,255);//颜色
int thickness = 4;//线条粗细
int lineType = 8;//线型
int baseLine;//相当于四线格的第三行高度
  • cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseLine);

2. 设置文字图像textImg尺寸格式

  • cv::Mat textImg=cv::Mat::zeros(textSize.height+baseLine,textSize.width,/*CV_8UC1*/img.type());
    • textSize.width 文字的宽度
    • textSize.height 文字的高度(相当于四线格的第一第二行高度)
    • baseLine 基线相对于最底部文本点的y坐标(相当于四线格的第三行高度)
      • 所以在设置文字的roi时高度应该是textSize.height+baseLine
      • 尤其是文字中含fgjpqy字母时不要忘记加baseLine
      • 虽然纯数字不含fgjpq但cv::getTextSize计算出的baseLine也不为0

在这里插入图片描述


3. 将文字绘制在文字图像textImg上

  • cv::putText(textImg,text,cv::Point(0,textSize.height+0.5*baseLine),fontFace,fontScale,color,thickness,lineType);
    • 注意putText第三个参数为左下角坐标不是左上角
    • 因为不含fgjpq不担心超出,这里再加上了0.5*baseLine,是为了在文字上下各留0.5*baseLine的空白,(倘若含fgjpq就不要加0.5*baseLine了,上方会超出图像)
  • 一开始误将坐标写为左上角坐标导致textImg基本没有写到文字

在这里插入图片描述

  • putText第三个参数的y坐标一开始设为textSize.height没加0.5*baseLine,导致文字底端紧贴图像底部,上方仍有空余不美观

在这里插入图片描述

  • 第三个参数设置为cv::Point(0,textSize.height+baseLine)的效果

在这里插入图片描述

  • 第三个参数设置为cv::Point(0,textSize.height+0.5*baseLine)的效果

在这里插入图片描述


4. 对文字图像textImg进行旋转

  • cv::rotate(textImg,textImg,cv::ROTATE_90_COUNTERCLOCKWISE);
    • cv::ROTATE_90_COUNTERCLOCKWISE 逆时针旋转90°
    • cv::ROTATE_90_CLOCKWISE 顺时针旋转90°

5. 在原图img上设置用来放置文字图像textImg的roi区域

5.1 矩形区域roi

  • cv::Mat textRoi=img(cv::Rect(leftTopPoint.x,leftTopPoint.y,width,height));
    • cv::Rect里的参数分别为 左上角坐标x,y值以及区域宽高

5.2 行列范围roi

  • cv::Mat textRoi=img(cv::Range(rowStart,rowEnd),cv::Range(colStart,colEnd));
    • cv::Range里的参数分别为起止行,列;注意不包含结束行/列,相当于左闭右开 [start,end)

6. 将文字图像textImg放置在roi区域上

6.1 copyTo

6.1.1 不设置掩膜

  • textImg.copyTo(textRoi);
    • 会将整个textImg贴在原图roi处,textImg上非文字部分的图像可能会遮住原图的部分信息,如下图
      在这里插入图片描述

6.2.2 设置掩膜

  • textImg.copyTo(textRoi,textImg);
    • 由于textImg设置了黑底白字,所以可以直接用它本身当掩膜(textRoi上只显示textImg在掩膜上不为0的像素),即只将textImg图像上的文字贴在了原图上
      在这里插入图片描述
  • 另一种掩膜思路(这个复杂一点 可结合思考copyTo的掩膜)
    • 将水印加在原图上,对于需要作为水印的图,首先将这张图由彩色图转换为单通道灰度图,再利用阈值将灰度图转换为二值图,那么这张二值图就会成为掩膜;在原图上取与掩膜图同样大小的roi区域;对两张图进行按位与bitwise_and(有0为0),掩膜上的黑色区域在roi上也是黑色的;其次对掩膜进行非运算取反操作bitwise_not(掩膜黑白颠倒),再将掩膜与水印图进行位与bitwise_and(掩膜上的黑色区域在水印图上也是黑色的,非黑色部分正好是roi上的黑色区域),最后将进行了掩膜的roi与水印图相加add()

6.2 + / add()

  • 图像+图像 img1=img2+img3;

    • 相加图像尺寸应相同,相同位置像素值相加(单通道灰度图为对应位置像素的灰度值相加,多通道为各通道的每个像素值相加)
  • 图像+标量 img1=img2+a;

    • img2各通道的每个像素值加a
  • +add()的区别

    • +sum=mod(a+b,256) (取模操作,超出255的取模,如和为300最后sum就为45;直接使加法时需谨慎,超出255的话很亮的区域反而变暗了)
    • add()sum=a+b>255 ? 255:a+b(饱和操作,超出255的设为255)
void cv::add(InputArray src1,InputArray src2,OutputArray dst,InputArray mask = noArray(),int dtype = -1)	

7. 整体流程代码

//获取文字尺寸
cv::Size textSize = cv::getTextSize(text, fontFace, fontScale, thickness, &baseLine);
//创建文字图像
cv::Mat textImg=cv::Mat::zeros(textSize.height+baseLine,textSize.width,img.type());
//将文字写到图像上
cv::putText(textImg,text,cv::Point(0,textSize.height+0.5*baseLine),fontFace,fontScale,color,thickness,lineType);
//对图像进行旋转
cv::rotate(textImg,textImg,cv::ROTATE_90_COUNTERCLOCKWISE);
//在原图上取图像大小roi
cv::Mat textRoi=img(cv::Rect(leftTopPoint.x,leftTopPoint.y,textImg.size().width,textImg.size().height));
//将文字图像贴到原图上
textImg.copyTo(textRoi,textImg);
//或者使用add()与上方代码效果相同(因为我的图是黑底白字的,其他颜色的可能会有些区别)
//cv::add(textImg,textRoi,textRoi);
//textRoi=textRoi+textImg;
  • 最终效果图 将文字横着写在图像竖线上方

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Swin-Unet: Unet-like Pure Transformer for Medical Image Segmentation论文解读

Swin-Unet: Unet-like Pure Transformer for Medical Image Segmentation 论文:[2105.05537] Swin-Unet: Unet-like Pure Transformer for Medical Image Segmentation (arxiv.org) 代码:HuCaoFighting/Swin-Unet: The codes for the work “Swin-Unet:…

LiveNVR监控流媒体Onvif/RTSP功能功能-支持GB35114接入国标流媒体平台接入说明

LiveNVR监控流媒体Onvif/RTSP功能功能-支持GB35114接入国标流媒体平台接入说明1、GB35114注册2、LiveNVR通过GB35114接入LiveGBS2.1、开启LiveGBS 35114功能2.2、 获取设备端证书给平台2.3、LiveGBS白名单中添加需要接入的国密设备2.4、导出LiveGBS平台端证书给设备&#xff08…

管理学实验的设计与实践结课作业

一、不同组织结构类型对组织的沟通效率会带来影响,这也是在组织结构设计过 程需要考虑的重要内容,但对于两者的关系无法准确界定。如在直线职能制的组织结构中,管理幅度和深度是影响是影响沟通效率的主要因素。请设计实验来验证分析直线职能制…

手动部署SQL审计平台Archery(连接mysql8.x)

安装Python和virtualenv从1.9.0版本开始,将不再支持python3.7及以下版本,手动安装也将使用3.9版本作为样例,移除yum安装方式# 安装依赖 yum install libffi-devel wget gcc make zlib-devel openssl openssl-devel ncurses-devel openldap-de…

分享81个PHP源码,总有一款适合您

PHP源码 分享81个PHP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 81个PHP源码下载链接:https://pan.baidu.com/s/18jo0nrQ6tCf-e1PAylItmQ?pwd3rxz 提取码&#xff…

Mysql之多表查询

简单测试 由于我们之前没学过多表查询 我们简单测试一下初学者认为的多表查询 SELECT * FROM emp,dept这是我们的输出结果 其实不难发现 1.返回的结果就是,第一张表一个个数据取出然后和第二张表所有组合 最后返回的是含有两张表的所有列 2.一共返回的记录数第一章…

【ES6篇新语法】(1)ES6介绍及常量声明、对象数组,附实例详解

【写在前面】 应一些粉丝的要求,整理一些ES6相关的文章,因此借这个岁末之际,给大家整理一篇ES6的相关的博客,不管是面试还是在实际的编程上,我们都常提到ES6这个词,可能前几年比较热门,希望大家…

焊接变形的原因以及防止焊接变形的措施

焊接变形的原因   在焊接过程中对焊件进行了局部的、不均匀的加热是产生焊接应力及变形的原因。焊接时焊缝和焊缝附近受热区的金属发生膨胀,由于四周较冷的金属阻止这种膨胀,在焊接区域内就发生压缩应力和塑性收缩变形,产生了不同程度的横向…

喜报!西门子低代码连续四年获评Gartner企业低代码应用平台魔力象限领导者

点击下载最新发布的Gartner魔力象限图™https://www.mendix.com/resources/gartner-magic-quadrant-for-low-code-application-platforms/?utm_mediumpr&utm_campaignMQ&utm_sourceMQ#formWrapper 想象一下,一个为持续数字化转型做好准备的组织会是什么样…

EXTI中断以及系统滴答定时器SysTick的配置和使用

前言 EXTI中断来判断按键按下 EXTI即外部中断/事件控制器,总共支持19个中断/事件请求。每一条中断线都有独立的使能和产生中断后的标志位。 上图可见,中断/时间线0-15,总共16条线分配给了IO,通过设置AFIO的AFIO_EXTICR1、AFIO_…

内核调试之Kdump的原理及配置

术语介绍生产内核(production kernel):产品或者线上服务器当前运行的内核。捕获内核(capture kernel):系统崩溃时,使用kexec启动的内核,该内核用于捕获生产内核当前内存中的运行状态…

【windows terminal】普通用户免密ssh登录阿里云linux服务器

创建用户 [rootxxx~]# adduser linuxcool创建密钥 使用如下命令创建密钥 [rootxxx~]# ssh-keygen -t rsa创建的密钥路径 Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. 将公钥导入authorized_keys&…

《Go 并发数据结构和算法实践》学习笔记 Day 2

系列文章目录 这是本周期内系列打卡文章的所有文章的目录 《Go 并发数据结构和算法实践》学习笔记 Day 1_jahentao的博客-CSDN博客 文章目录系列文章目录前言一、Skiplist是什么?(What)Skiplist的基本接口查找元素插入元素删除元素二、并行化改造1.并发查找2.并发删…

struts漏洞总结

目录 概述 struts2漏洞 S2-001 漏洞原理 复现 struts2漏洞 S2-005 原理 分析一下003 复现 struts2漏洞s2-007 struts2漏洞 S2-008 原理 复现 struts2漏洞 S2-009 原理 复现 struts2漏洞 S2-012 原理 复现 struts2漏洞 S2-013 原理 复现 struts2漏洞 S2-0…

闭包中的内存泄漏

一.闭包的内存泄漏 1.为什么有些AO对象就不会被销毁? 1)普通函数中 上述代码在执行foo函数的时候,内存中的过程。 执行完foo函数之后,foo的函数上下文被销毁了,那么就不会指向foo的AO对象了。 那么AO对象也会被销毁…

格创东智蝉联入选工信部工业互联网APP优秀解决方案名单

1月13日,工信部发布《2022年工业互联网APP优秀解决方案名单公示》,由格创东智研发的 “基于深度学习技术的 AI智能检测(天枢AI)APP 应用解决方案”、“面向泛半导体行业的设备自动控制(EAP)APP解决方案”入…

一文详解SPI通信原理

首先我们先了解一下单工、半双工、全双工是什么概念 概念:(Serial Peripheral Interface,串行外设接口),是一种全双工协议的外设总线,同步串行通信 单工:电视 半双工:呼叫机 全双工:电话 SPI是单主设备(Single Master)通信协议&#xff…

商业智能 BI 赋能年底的财务分析

职场中总有些不能说的秘密,比如月底和年底的时候,千万不要去惹财务!尤其是年底,财务部门需要统计分析一整年的费用支出和经营收入,各种结算分析,还有新一年的预算,数据量庞大、业务系统分散、报…

【SpringCloud14】SpringCloud Bus消息总线

1.概述(对于Config的加深和扩充) 1.1 分布式自动刷新配置功能 SpringCloud Bus配合SpringCloud Config使用可以实现配置的动态刷新 Spring Cloud Bus是用来将分布式系统的节点与轻量级消息系统链接起来的框架,它整合了Java的事件处理机制和…

Web(八)

XML概念&#xff1a;Extensible Markup Language 可扩展标记语言可扩展&#xff1a;标签都是自定义的。 <user> <student>功能* 存储数据1. 配置文件2. 在网络中传输xml与html的区别1. xml标签都是自定义的&#xff0c;html标签是预定义。2. xml的语法严格&#xf…