基于opencv的c++图像处理(灰度变换)

这篇具有很好参考价值的文章主要介绍了基于opencv的c++图像处理(灰度变换)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

基于opencv的c++接口,实现常用的图像灰度变换方法,包括了线性变换、图像反转、对数变换和伽马变换。

相关的opencv接口解析

CV_EXPORTS_W void normalize( InputArray src, InputOutputArray dst, double alpha = 1, double beta = 0,
                             int norm_type = NORM_L2, int dtype = -1, InputArray mask = noArray());

函数 cv::normalize 标准化缩放和移动输入数组元素
当 normType=NORM_MINMAX 时(仅适用于密集数组)。可选掩码指定要规范化的子数组。这意味着在子数组上计算范数或 min-n-max,然后修改该子数组以进行归一化。如果您只想使用掩码计算范数或最小值-最大值但修改整个数组,则可以使用 norm 和 Mat::convertTo。
@param src 输入数组。
@param dst 与 src 大小相同的输出数组。
@param alpha norm value 规范化到或范围归一化情况下的范围下限。
@param beta 范围归一化情况下的范围上限;它不用于规范标准化。
@param norm_type 规范化类型(参见 cv::NormTypes)。
@param dtype 为负时,输出数组与 src 类型相同;否则,它具有与 src 相同数量的通道和深度 =CV_MAT_DEPTH(dtype)。
@param mask 可选操作掩码。

enum NormTypes {
                /**
                \f[
                norm =  \forkthree
                {\|\texttt{src1}\|_{L_{\infty}} =  \max _I | \texttt{src1} (I)|}{if  \(\texttt{normType} = \texttt{NORM_INF}\) }
                {\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} =  \max _I | \texttt{src1} (I) -  \texttt{src2} (I)|}{if  \(\texttt{normType} = \texttt{NORM_INF}\) }
                {\frac{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}}    }{\|\texttt{src2}\|_{L_{\infty}} }}{if  \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_INF}\) }
                \f]
                */
                NORM_INF       = 1,
                /**
                \f[
                norm =  \forkthree
                {\| \texttt{src1} \| _{L_1} =  \sum _I | \texttt{src1} (I)|}{if  \(\texttt{normType} = \texttt{NORM_L1}\)}
                { \| \texttt{src1} - \texttt{src2} \| _{L_1} =  \sum _I | \texttt{src1} (I) -  \texttt{src2} (I)|}{if  \(\texttt{normType} = \texttt{NORM_L1}\) }
                { \frac{\|\texttt{src1}-\texttt{src2}\|_{L_1} }{\|\texttt{src2}\|_{L_1}} }{if  \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L1}\) }
                \f]*/
                 NORM_L1        = 2,
                 /**
                 \f[
                 norm =  \forkthree
                 { \| \texttt{src1} \| _{L_2} =  \sqrt{\sum_I \texttt{src1}(I)^2} }{if  \(\texttt{normType} = \texttt{NORM_L2}\) }
                 { \| \texttt{src1} - \texttt{src2} \| _{L_2} =  \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if  \(\texttt{normType} = \texttt{NORM_L2}\) }
                 { \frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}} }{if  \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2}\) }
                 \f]
                 */
                 NORM_L2        = 4,
                 /**
                 \f[
                 norm =  \forkthree
                 { \| \texttt{src1} \| _{L_2} ^{2} = \sum_I \texttt{src1}(I)^2} {if  \(\texttt{normType} = \texttt{NORM_L2SQR}\)}
                 { \| \texttt{src1} - \texttt{src2} \| _{L_2} ^{2} =  \sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2 }{if  \(\texttt{normType} = \texttt{NORM_L2SQR}\) }
                 { \left(\frac{\|\texttt{src1}-\texttt{src2}\|_{L_2} }{\|\texttt{src2}\|_{L_2}}\right)^2 }{if  \(\texttt{normType} = \texttt{NORM_RELATIVE | NORM_L2SQR}\) }
                 \f]
                 */
                 NORM_L2SQR     = 5,
                 /**
                 In the case of one input array, calculates the Hamming distance of the array from zero,
                 In the case of two input arrays, calculates the Hamming distance between the arrays.
                 */
                 NORM_HAMMING   = 6,
                 /**
                 Similar to NORM_HAMMING, but in the calculation, each two bits of the input sequence will
                 be added and treated as a single bit to be used in the same calculation as NORM_HAMMING.
                 */
                 NORM_HAMMING2  = 7,
                 NORM_TYPE_MASK = 7, //!< bit-mask which can be used to separate norm type from norm flags
                 NORM_RELATIVE  = 8, //!< flag
                 NORM_MINMAX    = 32 //!< flag
               };
CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst,
                                  double alpha = 1, double beta = 0);

函数可用于缩放,计算绝对值,并将结果转换为 8 位。
在输入数组的每个元素上,函数 convertScaleAbs 依次执行三个操作:缩放、取绝对值、转换为无符号 8 位类型。
在多通道数组的情况下,该函数独立处理每个通道。当输出不是 8 位时,可以通过调用 Mat::convertTo 方法(或使用矩阵表达式)模拟该操作,然后计算结果的绝对值。
@param src 输入数组。
@param dst 输出数组。
@param alpha 可选比例因子。
@param beta 可选增量添加到缩放值。

常用灰度变换公式

图像反转公式:s=255-r,其中,r表示原始图像的灰度级,s表示变换后的灰度级。
对数变换公式:s=clog(1+r),其中,r表示原始图像的灰度级,s表示变换后的灰度级,c为常数。
伽马变换公式:s=c
r^y,其中,r表示原始图像的灰度级,s表示变换后的灰度级,c为比例系数,y为幂数。
线性变换公式:s=a*r+b,其中,r表示原始图像的灰度级,s表示变换后的灰度级,a为比例系数,b为平移系数。

示例代码

grayTransform.h

#pragma once

#include <iostream>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\imgproc\imgproc.hpp>

using namespace std;
using namespace cv;
#define PROCESS_IMG_SUCESS 0
#define PROCESS_IMG_FAIL 1


namespace ImgEnhance
{
	//灰度变换
	class GrayscaleTransform
	{

	public:
		GrayscaleTransform() { cout << "GrayscaleTransform is being created" << endl; } // 这是构造函数声明
		~GrayscaleTransform() { cout << "GrayscaleTransform is being deleted" << endl; } // 这是析构函数声明

		int ImageInverse(cv::Mat srcImage, cv::Mat &dstImage);//图像反转//灰度线性变换最常见的就是图像反转:s=255-r
		int ImageLogTransform(cv::Mat srcImage, cv::Mat &dstImage,float c);//对数变换//s=c*log(1+r):其中,r表示原始图像的灰度级,s表示变换后的灰度级,c为常数。
		int ImageGammaTransform(cv::Mat srcImage, cv::Mat &dstImage, float c,float y);//伽马变换//s=c*r^y
		int ImageLinearTransform(cv::Mat srcImage, cv::Mat &dstImage, float a, float b);//线性变换//s=a*r+b

	};

}

grayTransform.cpp

#include"grayTransform.h"

int ImgEnhance::GrayscaleTransform::ImageInverse(cv::Mat srcImage, cv::Mat &dstImage)//图像反转
{
	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	int height = srcImage.rows;
	int width = srcImage.cols;
	
	Mat dst = Mat(height, width,CV_8UC1);
	for (int i = 0; i < height; i++)
	{
		uchar* p1 = dst.ptr<uchar>(i);
		uchar* p2 = srcImage.ptr<uchar>(i);
		for (int j = 0; j < srcImage.cols; j++)
		{
			p1[j] = 255 - p2[j];
		}
	}

	dstImage = dst.clone();

	return 0;
}

int ImgEnhance::GrayscaleTransform::ImageLogTransform(cv::Mat srcImage, cv::Mat &dstImage, float c)//对数变换//s=c*log(1+r)
{
	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	int height = srcImage.rows;
	int width = srcImage.cols;

	float pixels[256];
	for (int i = 0; i < 256; i++)
	{
		pixels[i] = c*log(1 + i);
	}
		
	Mat imageLog(height, width, CV_32FC1);
	for (int i = 0; i<height; i++)
	{
		float* p1 = imageLog.ptr<float>(i);
		uchar* p2 = srcImage.ptr<uchar>(i);
		for (int j = 0; j<width; j++)
		{
			p1[j] = pixels[p2[j]];
		}
	}
	//归一化到0~255  
	normalize(imageLog, imageLog, 0, 255, NORM_MINMAX);
	//转换成8bit图像显示  
	convertScaleAbs(imageLog, imageLog);

	dstImage = imageLog.clone();

	return 0;

}

int ImgEnhance::GrayscaleTransform::ImageGammaTransform(cv::Mat srcImage, cv::Mat &dstImage, float c, float y)//伽马变换//s=c*r^y
{
	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	int height = srcImage.rows;
	int width = srcImage.cols;

	float pixels[256];
	for (int i = 0; i < 256; i++)
	{
		pixels[i] = c*powf(i, y);
	}

	Mat imageGamma(height, width, CV_32FC1);
	for (int i = 0; i<height; i++)
	{
		float* p1 = imageGamma.ptr<float>(i);
		uchar* p2 = srcImage.ptr<uchar>(i);
		for (int j = 0; j<width; j++)
		{
			p1[j] = pixels[p2[j]];
		}
	}
	//归一化到0~255  
	normalize(imageGamma, imageGamma, 0, 255, NORM_MINMAX);
	//转换成8bit图像显示  
	convertScaleAbs(imageGamma, imageGamma);

	dstImage = imageGamma.clone();

	return 0;

}

int ImgEnhance::GrayscaleTransform::ImageLinearTransform(cv::Mat srcImage, cv::Mat &dstImage, float a, float b)//线性变换//s=a*r+b
{

	if (!srcImage.data || srcImage.channels() != 1)
	{
		return 1;
	}
	int height = srcImage.rows;
	int width = srcImage.cols;

	float pixels[256];
	for (int i = 0; i < 256; i++)
	{
		pixels[i] = a*i+b;
	}

	Mat imageLinear(height, width, CV_32FC1);
	for (int i = 0; i<height; i++)
	{
		float* p1 = imageLinear.ptr<float>(i);
		uchar* p2 = srcImage.ptr<uchar>(i);
		for (int j = 0; j<width; j++)
		{
			p1[j] = pixels[p2[j]];
		}
	}
	//归一化到0~255  
	normalize(imageLinear, imageLinear, 0, 255, NORM_MINMAX);
	//转换成8bit图像显示  
	convertScaleAbs(imageLinear, imageLinear);

	dstImage = imageLinear.clone();

	return 0;
}

test.cpp

#include"grayTransform.h"

ImgEnhance::GrayscaleTransform ImgG;//灰度变换

int main()
{
	// 读取源图像及判断
	cv::Mat srcImage = cv::imread("flower.jpg");
	if (!srcImage.data)
	{
		return 1;
	}
	cv::namedWindow("原始图", 0);
	cv::imshow("原始图", srcImage);
	// 转化为灰度图像
	cv::Mat srcGray;
	if (srcImage.channels() == 3)
	{
		cv::cvtColor(srcImage, srcGray, COLOR_RGB2GRAY);
	}
	else
	{
		srcGray = srcImage.clone();
	}
	cv::namedWindow("灰度图", 0);
	cv::imshow("灰度图", srcGray);

	cv::Mat inverseMat;
	// 灰度反转 图像
	ImgG.ImageInverse(srcGray, inverseMat);
	cv::namedWindow("灰度反转图", 0);
	cv::imshow("灰度反转图", inverseMat);

	cv::Mat imageLogTransformMat;
	float cl = 10;
	// 对数变换 图像
	ImgG.ImageLogTransform(srcGray, imageLogTransformMat,cl);
	cv::namedWindow("对数变换图", 0);
	cv::imshow("对数变换图", imageLogTransformMat);

	cv::Mat imageGammaTransformMat;
	float cg = 1;
	float yg = 0.5;
	// 伽马变换 图像
	ImgG.ImageGammaTransform(srcGray, imageGammaTransformMat, cg,yg);
	cv::namedWindow("伽马变换图", 0);
	cv::imshow("伽马变换图", imageGammaTransformMat);

	cv::Mat imageLinearTransformMat;
	float a = 0.5;
	float b = 1;
	// 线性变换 图像
	ImgG.ImageGammaTransform(srcGray, imageLinearTransformMat, a, b);
	cv::namedWindow("线性变换图", 0);
	cv::imshow("线性变换图", imageLinearTransformMat);

	cv::waitKey(0);

	return 0;

}

结果图

基于opencv的c++图像处理(灰度变换)文章来源地址https://www.toymoban.com/news/detail-439933.html

到了这里,关于基于opencv的c++图像处理(灰度变换)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Opencv 图像处理:图像基础操作与灰度转化

    本文已收录于Opencv系列专栏: 深入浅出OpenCV ,专栏旨在详解Python版本的Opencv,为计算机视觉的开发与研究打下坚实基础。免费订阅,持续更新。 1.图像格式 图像压缩比: 通过编码器压缩后的图象数字大小和原图象数字大小的压缩比。 BMP 格式 Windows系统下的 标准位图格式 ,

    2024年02月04日
    浏览(51)
  • 【OpenCV】 基础入门(二)图像基础概念 | 图像灰度化处理 | 图像二值化处理

      在计算机中用一般用 M x N 的矩阵来表示一幅尺寸大小为 M x N 的数字图像,矩阵元素的值就是该图像对应位置上的像素值。    对于计算机本地磁盘中的彩色图像,单机鼠标右键,选择“属性”,可以看到一幅图像的基本信息。 1、灰度图:   灰度图是每个像素只有一

    2024年04月14日
    浏览(51)
  • OpenCV常用功能——灰度处理和图像二值化处理

    1.1 cvtColor函数 函数原型: 功能 :转换图像颜色空间。 参数 : src: 输入图像。 code: 颜色空间转换代码。可以取常量cv2.COLOR_BGR2GRAY或cv2.COLOR_RGB2GRAY。 dst: 输出图像。 dstCn: 输出图像的通道数,如果设置为0,则跟随转换代码自动设置。 内置函数示例代码: 灰度处理的原理是将

    2024年02月08日
    浏览(62)
  • OpenCV数字图像处理基于C++:图像分割

    图像阈值化分割是一种常用的、传统的图像分割技术,因其 实现简单、计算量小、性能比较稳定 而成为图像分割中基本和应用广泛的分割技术。特别 适合于目标和背景占据不同灰度级范围的图像 。不仅 可以极大地压缩数据量 ,而且大大 简化了分析和处理的步骤 ,是进行

    2024年02月11日
    浏览(70)
  • 基于opencv的c++图像处理(图像二值化)

    基于opencv的c++接口,实现常用的图像二值化方法,包括了最大类间方差法(OTSU)、固定化阈值以及自适应阈值。 该函数将固定级别的阈值应用于多通道阵列。该函数通常用于从灰度图像中获取双层(二进制)图像(#compare 也可用于此目的)或用于去除噪声,即过滤掉值过小

    2024年02月07日
    浏览(51)
  • 图像处理之DCT图像压缩(基于c++ opencv实现)

    是老师布置的作业,拖到ddl才开始,opencv也才刚接触,有自己结合百度的一点理解,如有误,请谅解! 先贴一段在matlab上实现的代码,这个在网上都可以查到,就不赘述了 思路如下:      先划分处理块大小,对每个块分别进行DCT变换,再舍弃每个块中的高频系数,再进行

    2024年02月09日
    浏览(69)
  • OpenCV数字图像处理基于C++:边缘检测

    边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。有许多

    2024年02月05日
    浏览(60)
  • C#使用OpenCv(OpenCVSharp)图像处理实例:亮度、对比度、灰度

    本文实例演示C#语言中如何使用OpenCv(OpenCVSharp)对图像进行亮度、对比度、灰度处理。 目录 亮度和对比度原理 灰度 实例 图像亮度通俗理解便是图像的明暗程度,数字图像 f(x,y) = i(x,y) r(x, y) ,如果灰度值在[0,255]之间,则 f 值越接近0亮度越低,f 值越接近255亮度越

    2024年02月13日
    浏览(76)
  • 基于FPGA的图像灰度处理

            对于图像的灰度处理,原理与基于FPGA的图像反转相同,但算法不同。相交于基于FPGA的图像反转,基于FPGA的图像灰度处理操作时间由于FPGA的并行性,其处理时间与前者相同。虽然工作量大了4倍左右,但处理时间基本相同,在仿真中,仍在5.2ms完成了处理。凸显出

    2024年02月04日
    浏览(45)
  • 【OpenCV实现图像:使用OpenCV进行图像处理之透视变换】

    透视变换(Perspective Transformation)是一种图像处理中常用的变换手段,它用于将图像从一个视角映射到另一个视角,常被称为投影映射。透视变换可以用于矫正图像中的透视畸变,使得图像中的物体在新的视平面上呈现更加规则的形状。 透视变换通常涉及到寻找图像中的特定

    2024年02月03日
    浏览(64)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包