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

OPENCV C++(十)gramm矫正+直方图均衡化

两者都是只对单通道使用,对多通道的话 就需要分离通道处理再合并通道

 两种方法,第一个要运算次数太多了,第二个只需要查表

伽马矫正函数,这里用第二种方法,且写法有点高级

int gammaCorrection(cv::Mat srcMat, cv::Mat& dstMat, float gamma) {//建立查询表unsigned char lut[256];for (int i = 0; i < 256; i++){//saturate_cast,防止像素值溢出,如果值<0,则返回0,如果大于255,则返回255lut[i] = saturate_cast<uchar>(pow((float)(i / 255.0f), gamma) * 255.0f);}srcMat.copyTo(dstMat);MatIterator_<uchar> it, end;for (it = dstMat.begin<uchar>(), end = dstMat.end<uchar>(); it != end; it++) {*it = lut[(*it)];}return 0;}

就是建立了查找表,然后计算查找表,再遍历像素直接赋值查找表,就不用计算了。

	int readType = 0;Mat srcMat = imread("kjy.jpg");resize(srcMat, srcMat,Size(srcMat.rows*0.5, srcMat.rows * 0.5));cv::Mat dstMat;float gamma = GAMMA_FACTOR;if (srcMat.type() == CV_8UC1){gammaCorrection(srcMat, dstMat, gamma);}else {Mat channel[3];Mat out[3];float hist[3][256];//通道分离split(srcMat, channel);for (int i = 0; i < 3; i++) {gammaCorrection(channel[i], out[i], gamma);}merge(out, 3, dstMat);}imshow("src", srcMat);imshow("dst", dstMat);waitKey(0);destroyAllWindows();

这就是grammar矫正的代码

直方图均衡化(只对单通道有效果)多通道的话先分离通道再合并一样的

equalizeHist(srcMat, equalizeHistMat);

 

计算直方图函数


int calcIntenHist(const cv::Mat src, float* dstHist)
{//输入必为单通道图if (src.type() != CV_8UC1) {return -1;}memset(dstHist, 0, sizeof(float) * 256);int height = src.rows;int width = src.cols;//指针遍历for (int k = 0; k < height; k++){// 获取第k行的首地址const uchar* inData = src.ptr<uchar>(k);//处理每个像素for (int i = 0; i < width; i++){int gray = inData[i];dstHist[gray]++;}}//直方图归一化float norm = height * width;for (int n = 0; n < 256; n++) {dstHist[n] = dstHist[n] / norm;}return 0;
}

 还进行了归一化

直方图画画函数


int drawIntenHist(cv::Mat& histMat, float* srcHist, int bin_width, int bin_heght)
{histMat.create(bin_heght, 256 * bin_width, CV_8UC3);histMat = Scalar(255, 255, 255);float maxVal = *std::max_element(srcHist, srcHist + 256);for (int i = 0; i < 256; i++) {Rect binRect;binRect.x = i * bin_width;float height_i = (float)bin_heght * srcHist[i] / maxVal;binRect.height = (int)height_i;binRect.y = bin_heght - binRect.height;binRect.width = bin_width;rectangle(histMat, binRect, CV_RGB(255, 0, 0), -1);}return 0;
}

 float height_i = (float)bin_heght * srcHist[i] / maxVal;是防止不够高度大小 要进行的高度归一

直方图均衡化的完整代码:

	float srcHist[256];float dstHist[256];Mat dstHistMat;Mat srcHistMat;Mat histMat[3];Mat equalizeHistMat;cv::Mat dstMat1;int bin_width = 2;int bin_heigth = 100;if (srcMat.type() == CV_8UC1) {equalizeHist(srcMat, equalizeHistMat);imshow("src", srcMat);imshow("equalizeHistMat", equalizeHistMat);waitKey(0);destroyAllWindows();calcIntenHist(dstMat1, dstHist);drawIntenHist(dstHistMat, dstHist, 3, 100);imshow("dstMat hist", dstHistMat);calcIntenHist(srcMat, srcHist);drawIntenHist(srcHistMat, srcHist, 3, 100);imshow("srcMat hist", srcHistMat);waitKey(0);destroyAllWindows();}else{Mat channel[3];Mat out[3];float hist[3][256];split(srcMat, channel);for (int i = 0; i < 3; i++) {equalizeHist(channel[i], out[i]);calcIntenHist(out[i], hist[i]);drawIntenHist(histMat[i], hist[i], bin_width, bin_heigth);//按照channel编号命名窗口stringstream ss;ss << i;string histWindow = "Hist of chanel " + ss.str();string matWindow = "Image of chanel " + ss.str();imshow(histWindow, histMat[i]);imshow(matWindow, out[i]);}merge(out, 3, dstMat1);cv::Mat grayMat;cv::Mat graydstMat;cvtColor(srcMat, grayMat, CV_BGR2GRAY);cvtColor(dstMat1, graydstMat, CV_BGR2GRAY);//计算并绘制直方图calcIntenHist(graydstMat, dstHist);drawIntenHist(dstHistMat, dstHist, 3, 100);imshow("dstMat", dstMat1);imshow("dstMat hist", dstHistMat);calcIntenHist(grayMat, srcHist);drawIntenHist(srcHistMat, srcHist, 3, 100);imshow("srcMat hist", srcHistMat);imshow("srcMat", srcMat);waitKey(0);destroyAllWindows();}return 0;}

相关文章:

OPENCV C++(十)gramm矫正+直方图均衡化

两者都是只对单通道使用&#xff0c;对多通道的话 就需要分离通道处理再合并通道 两种方法&#xff0c;第一个要运算次数太多了&#xff0c;第二个只需要查表 伽马矫正函数&#xff0c;这里用第二种方法&#xff0c;且写法有点高级 int gammaCorrection(cv::Mat srcMat, cv::…...

并发——ThreadPoolExecutor 类简单介绍

文章目录 1 ThreadPoolExecutor 类分析2 推荐使用 ThreadPoolExecutor 构造函数创建线程池 线程池实现类 ThreadPoolExecutor 是 Executor 框架最核心的类。 1 ThreadPoolExecutor 类分析 ThreadPoolExecutor 类中提供的四个构造方法。我们来看最长的那个&#xff0c;其余三个…...

SharePoint 审核和监控工具

审核在顺利的 SharePoint 管理中起着重要作用&#xff0c;尤其是在满足法规遵从性和取证要求方面。为避免数据泄露&#xff0c;必须了解谁来自哪个组访问了哪个文档&#xff0c;以及谁创建或删除了网站或网站集。 审核 SharePoint 服务器 SharePoint采用率的提高导致企业在其…...

java+springboot+mysql法律咨询网

项目介绍&#xff1a; 使用javassmmysql开发的法律咨询网&#xff0c;系统包含超级管理员&#xff0c;系统管理员、用户角色&#xff0c;功能如下&#xff1a; 用户&#xff1a;主要是前台功能使用&#xff0c;包括注册、登录&#xff1b;查看法律领域&#xff1b;法律法规&a…...

无涯教程-Perl - getservbyport函数

描述 此功能转换协议PROTO的服务编号PORT,在标量context中返回服务名称,并在列表context中返回名称和相关信息- ($name,$aliases,$port_number,$protocol_name) 该调用基于/etc/services文件返回这些值。 语法 以下是此函数的简单语法- getservbyport PORT, PROTO返回值 …...

iOS开发-JsonModel的学习及使用

IOS JsonModel的学习及使用 当我们从服务端获取到json数据后的时候&#xff0c;我们需要在界面上展示或者保存起来&#xff0c;下面来看下直接通过NSDictionary取出数据的情况。 NSDictionary直接取出数据的诟病。 NSString *name [self.responseObj objectForKey:"nam…...

jquery 遍历所有元素

要遍历所有元素&#xff0c;您可以使用 jQuery 的 .each() 方法。以下是使用 .each() 方法来遍历所有元素的示例代码&#xff1a; $(selector).each(function() {// 在这里编写处理每个元素的代码// 使用 $(this) 来访问当前迭代的元素 });在上面的代码中&#xff0c;您需要将…...

Tik Tok跨境电商新风向,跨境卖家该如何布局?

TikTok作为优质的中国出海企业&#xff0c;近年来在电商业务上的布局也越来越广泛&#xff0c;除了之前的内容电商&#xff0c;TikTok Shop也上线了商城业务&#xff0c;补全了“人找货”的场景&#xff0c;为卖家增加了在直播、短视频之外的新流量来源。 TikTok美国小店现状 …...

OR36 链表的回文结构 题解

题目描述&#xff1a;链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 对于一个链表&#xff0c;请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法&#xff0c;判断其是否为回文结构。 给定一个链表的头指针A&#xff0c;请返回一个bool值&#xff0c;代表其是否为回文结…...

“去没有天花板的地方” | 小红书用户情绪数据

最近&#xff0c;话题#人就要待在没有天花板的地方#社媒讨论度居高不下&#xff0c;小红书相关话题近90天互动量超百万。 生活的无常之外&#xff0c;越来越多人渴望与大自然更深层次的链接&#xff0c;以此寻找情绪的不同出口。或许&#xff0c;剖析这些情绪的生成机理&#x…...

Java文件操作(遍历目录中的文件,找到并删除有指定关键字的文件)

对于通过java对文件继续读取和写入的操作推荐看读取文件和写入文件操作 题目 扫描指定目录中的文件&#xff0c;并找到名称中包含指定字符的所有普通文件&#xff08;不包括目录&#xff09;&#xff0c;并后续询问用户是否要删除该文件 题目分析 实际上题目就要求我们对一个…...

MySQL单表查询

单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varch…...

苹果正在测试新款Mac mini:搭载M3芯片 配备24GB大内存

据悉苹果目前正在测试新的Mac机型&#xff0c;亮点是采用最新的M3芯片。 据报道&#xff0c;首款搭载M3芯片的设备应该是13英寸的MacBook Pro和重新设计的MacBook Air&#xff0c;Mac mini机型并不在名单上。 M3和M2同样拥有最多8个核心&#xff0c;分别为4个性能核和4个能效核…...

redis的缓存更新策略以及如何保证redis与数据库的数据一致性

redis的缓存更新策略有这么几种&#xff1a; 1、由应用直接和redis以及数据库相连接&#xff1a; 查询数据时&#xff0c;应用去redis中查询&#xff0c;查不到的话再由应用去数据库中查询&#xff0c;并将查询结果放在redis&#xff1b; 更新数据时&#xff…...

k8s--使用cornJob定时执行sql文件

CronJob apiVersion: batch/v1beta1 kind: CronJob metadata:name: hello spec:schedule: "0 * * * *"jobTemplate:spec:template:spec:containers:- name: postgres-alpineimage: xxxximagePullPolicy: IfNotPresentcommand:- psql- -h- 数据库服务地址- -d- 数据库…...

Qt事件过滤器

1 介绍 事件过滤器是一种机制&#xff0c;当某个QObject没有所需要的事件功能时&#xff0c;可将其委托给其它QObject&#xff0c;通过eventFilter成员函数来过滤实现功能。 2 主要构成 委托&#xff1a; ui->QObject1->installEventFilter(QObject2); eventFilter声明 …...

Java基础集合框架学习(上)

文章目录 初识基础框架为什么使用集合框架集合框架的继承关系ArrayList入门案例单元测试和增删改查单元测试的注意事项LinkedList入门案例ArrayList底层是数组LinkedList底层是链表ArrayList和LinkedList选型ArrayList存放DOG对象 初识基础框架 Java基础集合框架是Java编程语言…...

北京多铁克FPGA笔试题目

1、使用D触发器来实现二分频 2、序列检测器&#xff0c;检测101&#xff0c;输出1&#xff0c;其余情况输出0 module Detect_101(input clk,input rst_n,input data, //输入的序列output reg flag_101 //检测到101序列的输出标志 );parameter S0 2d0;S1 2d1;S2 2d2;S4 …...

从初学者的角度来理解指针常量和常量指针

重新理解指针常量&#xff0c;常量指针 应用 我先提一个问题&#xff1a;知道指针常量&#xff0c;常量指针存在的作用是什么吗&#xff1f; 先了解它们存在的作用再去理解它们&#xff0c;或许更轻松些。 比如配置文件读取&#xff1a;在许多工程中&#xff0c;配置文件用于…...

C# OpenCvSharp 去水印 图像修复

效果 项目 VS2022.net4.8OpenCvSharp4 代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; usi…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...