opencv学习笔记(5): 图像预处理(图像格式和通道、点运算)

1. 图像格式和通道

1.1 图像格式

 图像格式是指计算机存储图像的格式。OpenCV目前支持的图像格式包括Windows位图文件BMP、DIB,JPEG文件JPEG、JPG、JPE,便携式网络图形文件PNG等。

①. BMP

BMP(全称Bitmap,位图)是Windows操作系统中的标准图像文件格式,可以分成两类——设备相关位图(Device Dependent Bitmap,DDB)和设备无关位图(Device Inpendent Bitmap,DIB),使用非常广。BMP采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。此种存储格式支持RGB、灰度、索引、位图等色彩模式,但不支持alpha通道,是Windows操作系统环境下最不容易出错的文件保存格式之一。

②. JPEG

JPEG格式是最常见的,也是用得最多的图像格式之一,被大多数的图像处理软件所支持。JPEG格式的图像还被广泛应用于网页的制作。该格式还支持CMYK、RGB和灰度色彩模式,但不支持alpha通道。其优点为兼容性好、传输速度快、占用内存小。

③. PNG

PNG(全称Portable Network Graphics),便携式网络图形是一种无损压缩的位图格式。其试图代替GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。PNG格式具有压缩比高、生成文件体积小的特点。

1.2 通道分离和合并

在自然界中,颜色本身非常容易受到光照的影响,RGB图像像素值变化很大,而梯度信号能提供更本质的信息。三通道转为单通道后,运算量大大减少,便于后续处理。图像处理不一定需要对R、G、B 3个分量都进行处理。在图像处理中,尤其是处理多通道图像时,有时需要对各个通道进行分离,分别处理;有时还需要对分离处理后的各个通道进行合并,重新合并成一幅多通道的图像。 在OpenCV中,实现图像通道的分离与合并的函数分别为cv::split()和cv::merge()。

1.2.1 通道分离

split()函数用于将一个多通道数组分离成几个单通道数组。其C++版本的两个定义,分别如下。

void split(const Mat&src, Mat*mvbegin)
void split(InputArray m,OutputArrayOfArrays mv)

参数解析如下:

const Mat & 类型的原图像src或者InputArray 类型的m:表示待分离图像的多通道数组。
Mat*mvbegin或者OutputArrayOfArrays mv:表示分离后图像的Mat数组首地址,或者OutputArrayOfArrays类型的mv,即一个vector <Mat>对象。

举例:

// 1.分离vector<Mat> channels; //通道数组Mat imageBlueChannel;Mat imageGreenChannel;Mat imageRedChannel;Mat srcImage = imread("C:/Users/27844/Desktop/icon.jpg", 1);//flag=1,载入三通道图像if (!srcImage.data) {std::cout <<"图像读入失败!" << std::endl;exit(1);}//把一个三通道图像转化为3个单通道图像split(srcImage, channels);imageBlueChannel = channels.at(0);imageGreenChannel = channels.at(1);imageRedChannel = channels.at(2);//分别显示分离的单通道图像imshow("源图像", srcImage);imshow("<1>蓝色通道图像", imageBlueChannel);imshow("<2>绿色通道图像",imageGreenChannel);imshow("<3>红色通道图像",imageRedChannel);waitKey(0);

 运行结果:

1.2.1 通道合并

merge()函数是split()函数的逆向操作——将多个数组合并成一个多通道的数组。它通过组合一些给定的单通道数组,将这些孤立的单通道数组合并成一个多通道数组,从而创建出一个由多个单通道阵列组成的多通道阵列。它有如下两个基于C++的多态函数定义。 

void merge(const Mat*mv,size_tcount,OutputArray dst)
void merge(InputArrayOfArrays mv,OutputArray dst)

参数解析如下:

  • 第一个参数mv:图像矩阵数组,表示需要被合并的输入矩阵或vector容器的阵列,这个mv参数中所有的矩阵必须有着一样的尺寸和深度。
  • 第二个参数count:需要合并矩阵的个数,当mv为空数组时,代表输入矩阵的个数,这个参数显然必须大于1。
  • 第三个参数dst:输出矩阵或图像,和mv[0]拥有一样的尺寸和深度,并且通道的数量是矩阵列中通道的总数。

 举例:

// 2.合并//对拆分的数据进行合并Mat mergeImage;merge(channels, mergeImage);//合并imshow("rgb", mergeImage);waitKey(0);

2. 点运算

点运算是将输入图像映射为输出图像的方法,输出图像每个像素点的灰度值仅由对应的输入像素点的值决定。

点运算常用于改变图像的灰度范围及分布。因作用性质,点运算有时也被称为对比度增强、对比度拉伸或灰度变换。点运算实际上是灰度到灰度的映射过程,设输入图像为A( x , y ),输出图像为B( x , y ),则点运算可表示为B( x , y )= f [A (x , y )],即点运算完全由灰度映射函数 s = f ( r )决定, r 和 s 分别为A和B图像在( x , y )的灰度, f ()为变换函数。点运算不会改变图像内像素点之间的空间关系,点运算包括图像灰度变换、直方图处理、伪彩色处理等技术。

2.1 像素点亮度操作

对图像中每个像素加上(或减去)一个常数。设像素亮度为 v , b 是亮度常数,公式为 v = v + b ,如果 b 为正数,则像素亮度增强,如果 b 为负数,则像素亮度减弱。

 在图像处理方面,无论加、减、乘、除,结果都可能会超出一个像素灰度值的范围(0~255),其中saturate_cast()函数的作用是当运算完之后,结果为负则转为0,结果超出255则转为255。下面的代码对像素亮度增加5:

for (int i = 0; i < Row; i++)
{for (int j = 0; j < Col; j++){for( int c = 0; c < 3; c++ )Scr.at<Vec3b>(i, j)[c]= saturate_cast<uchar> (Scr.at<Vec3b>(i, j)[c]+5 );}
}

2.2 图像卷积操作(也叫掩膜操作)

2.2.1 卷积 

 图像卷积是对图像进行处理时最常用的方法之一,如去噪、滤波、边缘提取等都要用到卷积函数,其目的之一是使各个目标之间的差距变得更大。卷积在数字图像处理中常见的应用为锐化(突出图像上物体的边缘、轮廓,或某些线性目标要素的特征)和边缘提取。数字图像是一个二维的离散信号,对图像做卷积操作其实就是利用卷积核(卷积模板)在图像上滑动,将图像点上的像素灰度值与对应的卷积核上的数值相乘,然后将所有相乘后的值相加作为卷积核中间像素对应的图像上像素的灰度值,并让卷积核最终滑动完所有像素的过程。

卷积值的计算过程如下:

(1)将核的锚点(中心点)放在要计算的像素上,卷积核剩余的部分对应在图像相应的像素上。

(2)将卷积核中的系数和图像中相应的像素值相乘,并求和。

(3)将最终结果赋值给锚点对应的像素。 

(4)通过将卷积核在整张图像中滑动,重复以上计算过程,直到处理完所有的像素。

卷积核的选择有以下一些规则:

  • 卷积核的大小一般是奇数,这样的话它就是按照中间的像素点中心对称的,所以卷积核的尺寸一般都是3x3、5x5或者7x7。有中心,也就有了半径,例如5x5大小的卷积核的半径就是2。
  • 卷积核所有的元素之和一般应等于1,这是为了维持源图像的能量(亮度)守恒。
  • 如果矩阵中所有元素之和大于1,那么卷积后的图像就会比源图像更亮;反之,如果小于1,那么得到的图像就会变暗。如果和为0,图像虽然不会变黑,但也会非常暗。
  • 卷积后的结果可能会出现负数或者大于255的数值。对于这种情况,将值直接截断到0到255之间即可。对于负数,也可以取绝对值。

 2.2.2 卷积操作

 OpenCV中,使用filter2D()函数完成图像卷积操作。其函数定义如下。

CV_EXPORTS_W void filter2D(
InputArray src, 
OutputArray dst, 
int ddepth,
InputArray kernel, 
Point anchor=Point(-1,-1),
double delta=0, 
int borderType=BORDER_DEFAULT );

 参数解析如下:

  • Input Array src:输入图像。
  • Output Array dst:输出图像。输出图像和输入图像具有相同的尺寸与通道数量。
  • int ddepth:目标图像深度。当输入值为-1时,目标图像深度和源图像深度保持一致。
  • Input Array kernel:卷积核,是一个矩阵。
  • Point anchor:内核的基准点(anchor)。其默认值为(-1,-1),说明基准点位于核的中心位置。基准点即核中与进行处理的像素点重合的点。
  • double delta:在储存目标图像前可选的添加到像素的值,默认值为0。
  • int border Type:像素向外逼近的方法,默认值是BORDER_DEFAULT。
    // 1.第一种方式Mat src, dst;src = imread("C:/Users/27844/Desktop/icon.jpg");if (!src.data) {cout << "open picture error!!" << endl;}CV_Assert(src.depth() == CV_8U);//图像深度imshow("src", src);//显示源图像int cols = (src.cols - 1) * src.channels();//由于最外围的一圈像素点没办法进行图像掩模,所以减1int rows = src.rows;//实际行数int offsets = src.channels();//通道数dst = Mat(src.size(), src.type());//大小、类型与源图像等同for (int row = 1; row < (rows - 1); row++) {const uchar*pre = src.ptr<uchar>(row - 1);//上一行const uchar* cur = src.ptr<uchar>(row);//当前行const uchar* next = src.ptr<uchar>(row + 1);//下一行uchar* output = dst.ptr<uchar>(row);for (int col = offsets; col < cols; col++) {output[col] = saturate_cast<uchar>(5 * cur[col] - (cur[col - offsets] + cur[col + offsets] + pre[col] + next[col]));}}imshow("dst", dst);
// 2.第二种方式:使用filter2D()函数Mat image = imread("C:/Users/27844/Desktop/icon.jpg");imshow("begin",image);// 定义一个卷积核Mat kernel = (Mat_<double>(3,3)<<-1,0,1,-2,0,2,-1,0,1);Mat dstImage; //结果图filter2D(image,dstImage,image.depth(),kernel);imshow("end",dstImage);waitKey(0);

代码中通过Mat_类代替Mat类来简化代码,Mat_类与Mat类的使用方法类似,具体如下。

Mat_<float> cMatrix = Mat::eye(3, 3, CV_32F);
∥"3,3"表示3行3列,且对角为1的矩阵;" CV_32F"表示0~1.0之间的32位浮点数
cMatrix(0, 0) = 2.5;
cout << cMatrix(0,0) << endl;//输出结果2.5

如果是定义为Mat类,则需要进行如下操作。

Mat testM = Mat::eye(3, 3, CV_32F);
testM.at<float>(0, 0) = 2.5;
cout << testM.at<float>(0,0) << endl;//输出结果2.5

 不同的卷积操作只需改变卷积核即刻,下面是几个常见的卷积核:

  • 平滑均值滤波卷积核。平滑均值滤波卷积核如图所示。该卷积核取9个值的平均值代替中间像素值,所以能起到平滑的效果。

  • 高斯平滑滤波卷积核。高斯平滑滤波卷积核如图所示。高斯平滑水平和垂直方向呈现高斯分布,更突出了中心点在像素平滑后的权重,相比均值滤波有着更好的平滑效果。

  • 图像锐化卷积核。图像锐化卷积核如图所示。该卷积利用了图像中的边缘信息有着比周围像素更高的对比度这一特点,经过卷积之后这种对比度进一步增强,从而使图像显得棱角分明、画面清晰,起到锐化图像的效果。

 2.3 图像反转

       反转变换适用于增强嵌入在图像暗色区域的白色或灰色细节,特别是当黑色面积较大时。灰度级范围为[0, −1]的图像反转可定义为 −1− ,其中, 为反转目标图像某点的灰度值, 为源图像对应点的灰度值, 为灰度级数(例:位深度为8位的是0~255)。

void function3()
{// 图像反转// 1.第一种方式Mat src = imread("C:/Users/27844/Desktop/icon.jpg");if(src.empty()){return;}int height = src.rows; //Mat对象行数int width = src.cols * src.channels();//Mat对象的列数乘通道数//显示图像imshow("src",src);// 将图像反转for(int i =0;i<height;++i){for(int j=0;j<width;++j){src.at<uchar>(i,j) = 255 - src.at<uchar>(i,j); //每一个像素反转}}//再次显示图像imshow("dst",src);// 2.第二种方式:bitwise_not()函数Mat dst;bitwise_not(src,dst);imshow("dst2",dst);waitKey(0);}

运行结果:

2.4 对数变换(对每个像素点的像素值进行对数运算)

对数变换可以拉伸范围较窄的低灰度值,同时压缩范围较宽的高灰度值;可以用来扩展图像中的暗像素值,同时压缩亮像素值。对数变换的一般表达式如下。

= c log(1+ ) (2-1)

其中,c为常数,1+ 可以使函数向左移一个单位,得到的 均大于0。

假设 r ≥0,进行对数变换时窄带低灰度输入图像值将映射为宽带输出值。

//对数变换举例//定义对数变换模块
void log_transfor(Mat& image, Mat& result)
{result = image.clone();int rows = image.rows,cols = image.cols;for (int i = 0; i < rows;i++){for (int j = 0;j < cols; j++){for (int k = 0;k < 3;k++){// 对数变换result.at<Vec3b>(i, j)[k] = 31 * log2(1 + image.at<Vec3b>(i, j)[k]);}}}
}
void function4()
{// 1.对数变换Mat image = imread("C:/Users/27844/Desktop/icon.jpg");Mat result;log_transfor(image,result);imshow("input",image);imshow("output",result);waitKey(0);}

2.5 幂律变换

幂律变换又叫伽马变换,和对数变换的原理差不多,只是参数多了一个,可变宽带的输入像素值范围可选,但是把低值带拉伸还是把高值带拉伸则取决于伽马的设定。

幂律变换的基本形式如下。

cr γ (2-2)

其中, 和 分别表示处理前后的像素值, 和 γ 为正常数。

  • 幂律变换通过幂次变换曲线中的 γ 值把输入的窄带值映射到宽带输出值。
  • 当 γ >1时,把输入的窄带暗值映射到宽带输出亮值,提高图像中亮区域的对比度。
  • 当 γ <1时,把输入高值映射为宽带,图像整体灰度值增大,提高图像暗区域中的对比度。

2.6 线性变换

 线性变换可分为线性变换和线性分段变换。线性变换是灰度变换的一种,图像的灰度变换通过建立灰度映射来调整源图像的灰度,从而达到图像增强的目的。

一般成像系统只具有一定的亮度范围,亮度的最大值与最小值之比称为对比度。由于形成图像的系统亮度有限,图像常出现对比度不足的问题,使人眼观看图像时获得的视觉效果很差,通过变换法可以大大改善图像的视觉效果。线性变换公式可以表示为 g ( x , y ) = k × f ( x , y ) + b 。其中 g ( x , y )表示变换后的目标像素值, f ( x , y )表示原图像素值, k 表示斜率, b 表示截距。 k 的取值和变换作用有以下4种情况。

  • 当 >1时,可用于增加图像的对比度。图像的像素值在变换后全部增大,整体显示效果被增强。
  • 当 = 1时,常用于调节图像亮度。
  • 当0< <1时,效果与 >1时相反,图像的对比度和整体效果都被削弱。
  • 当 <0时,源图像较亮的区域变暗,而较暗的区域会变亮。此时可以使函数中的 =−1、 =255让图像实现反色效果。

OpenCV中使用convertScaleAbs()函数与convertTo()函数对图像进行线性变换,其中convertScaleAbs()函数定义如下。

void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0);

参数解析如下:

  • InputArray src:输入图像。
  • OutputArray dst:输出图像。
  • double alpha:缩放因子。
  • double beta :缩放后的固定值,偏移量。

 注意,src和dst的类型与通道数相同。 

对于convertTo()函数,OpenCV主要支持单通道和三通道的图像,并且此时要求其深度为8位和16位无符号(即CV_16U),而其他一些数据类型是不支持的,例如float型等。如果Mat类型数据的深度和通道数不满足上面的要求,则需要使用convertTo()函数和cvtColor()函数来进行转换。convertTo()函数负责转换数据类型不同的Mat对象,即可以将类似float型的Mat对象转换为imwrite()函数能够接受的类型。convertTo()函数定义如下。

src.convertTo(dst, type, scale, shift);

参数解析如下:

  • dst:目的矩阵。
  • type:需要输出的矩阵类型,或者是输出矩阵的深度,如果是负值(常用−1),则输出矩阵和输入矩阵类型相同。
  • scale和shift:缩放参数,也可以写为alpha和beta。

 线性变换分为 全域线性变换 和 分段线性变换

void function5()
{// 线性变换// 1.使用convertScaleAbs()函数Mat src = imread("C:/Users/27844/Desktop/icon.jpg");Mat dst;convertScaleAbs(src,dst,1.5,10);imshow("src",src);imshow("dst",dst);// 2.使用convertTo()函数Mat dst2;src.convertTo(dst2,1,20);imshow("dst2",dst2);waitKey(0);}

 2.7 图像灰度化

我们平时看到的图像大部分都是彩色图像,在计算机中用RGB(红绿蓝)颜色模式显示图像,RGB 3个分量的取值范围都是0~255,从光学原理上按照不同的亮度比例进行颜色调配。如RGB(255,255,0)将红色与酸橙色(亮绿色)进行调配表示为黄色,RGB(128,0,128)将栗红色(暗红色)与海军蓝(深蓝色)混合为紫色。在RGB模型中,在R=G=B时,彩色会在视觉上呈现出一种灰色,其中R、G、B的值叫灰度值,灰度范围为0(黑色)到255(白色)。灰度值是形容黑白图像的,亮度值是形容彩色图像的。如果需要把彩色图像转换成黑白图像,那么亮度值就会作为转换后的黑白图像的灰度值。

在图像处理时,如果采用RGB模式进行计算,那么需要分别对RGB的3个分量进行处理,而且实际上RGB并不能反映图像的形态特征,只是从光学原理上进行颜色的调配。所以将彩色照片转换为灰度图进行统一处理,这个操作称为图像灰度化。

图像灰度化通常有两种方法:平均值法 加权平均法

平均值法直接将彩色图像中的3个分量亮度求平均得到灰度值,公式如下: 

 而由于人眼对绿色的敏感度最高,对蓝色的敏感度最低,因此,对RGB 3个分量进行加权平均能得到更合理的灰度图,公式如下:

 

举例 :

void function6()
{// 图像灰度化Mat src = imread("C:/Users/27844/Desktop/icon.jpg");imshow("src",src);//平均值法,与彩色图像大小相同,通道数为1Mat gray1(src.rows,src.cols,CV_8UC1);for(int i=0;i<src.rows;i++){for(int j=0;j<src.cols;j++){gray1.at<uchar>(i,j) = (src.at<uchar>(i,j*3) + src.at<uchar>(i,j*3 + 1) + src.at<uchar>(i,j*3 + 2)) / 3;}}//加权平均值法Mat gray2(src.rows,src.cols,CV_8UC1);for(int i=0;i<src.rows;i++){for(int j=0;j<src.cols;j++){gray2.at<uchar>(i,j) = (src.at<uchar>(i,j*3)*11 + src.at<uchar>(i,j*3 + 1)*59 + src.at<uchar>(i,j*3 + 2)*30) / 100;}}imshow("gray1",gray1);imshow("gray2",gray2);waitKey(0);
}

 运行结果:

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

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

相关文章

VMware workstation的3种网络类型

虚拟机想要和主机进行通信必须借助网桥或者交换机&#xff0c;VMware workstation提供了3种网络交换机&#xff1a;仅主机类型交换机、NAT类型交换机、桥接类型交换机。 介绍下这三种类型的交换机 仅主机类型 通过VMware workstation添加一个仅主机类型的虚拟交换机后&#…

【Java数据结构】树】

【Java数据结构】树 一、树型结构1.1 概念1.2 特点1.3 树的类型1.4 树的遍历方式1.5 树的表示形式1.5.1 双亲表示法1.5.2 孩子表示法1.5.3 孩子双亲表示法1.5.4 孩子兄弟表示法 二、树型概念&#xff08;重点&#xff09; 此篇博客希望对你有所帮助&#xff08;帮助你了解树&am…

Java Lock ConditionObject 总结

前言 相关系列 《Java & Lock & 目录》&#xff08;持续更新&#xff09;《Java & Lock & ConditionObject & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Java & Lock & ConditionObject & 总结》&#xff08;学习…

SLAM|1. 相机投影及相机畸变

一个能思考的人&#xff0c;才真是一个力量无边的人。——巴尔扎克 本章主要内容&#xff1a; 1.针孔相机模型 2.相机成像的几个坐标系图像 3.畸变及相机标定 本节主要介绍在照相机拍摄过程中&#xff0c;现实物体如何跟照片上的像素关联起来&#xff0c;具体涉及相机成像的物…

服务器数据恢复—异常断电导致服务器挂载分区无法访问的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌服务器同品牌存储&#xff0c;Linux centos7EXT4文件系统。 服务器故障&#xff1a; 意外断电导致服务器操作系统不能正常启动。经过修复后系统可以正常启动&#xff0c;但是挂载的分区无法正常访问。使用fsck修复这个问题分区&#xff…

[含文档+PPT+源码等]精品基于PHP实现的培训机构信息管理系统的设计与实现

基于PHP实现的培训机构信息管理系统的设计与实现背景&#xff0c;可以从以下几个方面进行阐述&#xff1a; 一、社会发展与教育需求 随着经济的不断发展和人口数量的增加&#xff0c;教育培训行业迎来了前所未有的发展机遇。家长对子女教育的重视程度日益提高&#xff0c;课外…

基于SSM+小程序的童装商城管理系统(商城3)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM小程序的童装商城管理系统实现了管理员及用户。 1、管理员实现了 首页、个人中心、用户管理、分类列表管理、童装商城管理、系统管理、订单管理。 2、用户实现了 注册、登录、首…

行为设计模式 -命令模式- JAVA

命令模式 一.简介二. 案例2.1 接收者&#xff08;Receiver&#xff09;2.2 命令接口实现对象&#xff08;ConcreteCommand&#xff09;2.3 调用者&#xff08; invoker&#xff09;2.4 获取Receiver对象2. 5 装配者客户端测试 三. 结论3.1 要点3.2 示例 前言 本设计模式专栏写了…

LCR 024. 反转链表 最细图片逐行解析过程

LCR 024. 反转链表 给定单链表的头节点 head &#xff0c;请反转链表&#xff0c;并返回反转后的链表的头节点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例…

云计算平台上的DevOps实践

文章目录 什么是DevOps云计算平台上的DevOps优势自动化部署弹性伸缩地理分布 实施DevOps的关键组件版本控制系统持续集成/持续交付工具配置管理工具监控和日志管理 实践案例使用AWS CodePipeline进行持续集成/持续交付利用AWS Auto Scaling实现弹性使用AWS CloudFormation进行基…

DIY可视化-uniapp悬浮菜单支持拖动、吸附-代码生成器

在Uniapp中&#xff0c;悬浮菜单支持拖动和吸附功能&#xff0c;可以为用户带来更加灵活和便捷的操作体验。以下是对这两个功能的详细解释&#xff1a; 悬浮菜单支持拖动 提高用户体验&#xff1a;用户可以根据自己的需要&#xff0c;将悬浮菜单拖动到屏幕上的任意位置&#x…

微信小程序 - 动画(Animation)执行过程 / 实现过程 / 实现方式

前言 因官方文档描述不清晰,本文主要介绍微信小程序动画 实现过程 / 实现方式。 实现过程 推荐你对照 官方文档 来看本文章,这样更有利于理解。 简单来说,整个动画实现过程就三步: 创建一个动画实例 animation。调用实例的方法来描述动画。最后通过动画实例的 export 方法…

Kafka认证时Successfully logged in真的认证成功了?

背景 某个应用需要配置 Kafka 集群信息&#xff0c;且需要在验证集群是否可达。基本实现思路是创建一个生产者对象&#xff0c;然后发送一条测试数据&#xff0c;调用 Producer 的 send 方法发送消息后&#xff0c;再调用 get() 方法&#xff0c;即同步发送消息&#xff0c;测…

基于spootboot学生选课系统设计与实现

资料下载 https://download.csdn.net/download/qq_63753925/89888794 https://download.csdn.net/download/qq_63753925/89888793 https://download.csdn.net/download/qq_63753925/89885091 https://download.csdn.net/download/qq_63753925/89882320 摘 要 近年来&#xf…

机器人转人工时,开启实时质检(mod_cti基于FreeSWITCH)

文章目录 前言联系我们实现步骤1. 修改拨号方案2. 启用拨号方案 前言 在客户与机器人对话中&#xff0c;是不能开启质检功能的。因为机器人识别会与质检识别产生冲突。如果用户想通过机器人转接到人工时&#xff0c;开启质检功能&#xff0c;记录客户与人工之间的对话。应该如…

MySQL史上最全总结

MySQL学习笔记 安装与配置myini文件内容&#xff1a;初始化MySQL: MySQL语法&#xff1a;SQL-DDL数据库1.创建数据库2.查看数据库3.修改4.删除 数据库中的表管理1.创建表2.查找3.修改4.删除5.截断表 SQL-DML1.添加数据1.1插入多条数据1.2表内容复制 2.修改数据3.删除 TRUNCATE和…

Android中的epoll机制

深入理解Android中的epoll机制 在Android系统中&#xff0c;epoll广泛用于高效管理网络和文件的I/O操作。它通过减少CPU资源消耗和避免频繁的内核态-用户态切换&#xff0c;实现了在多连接、多任务环境中的高性能。epoll的特性使其非常适合Android系统中网络服务器、Socket通信…

php伪协议和move_uploaded_file、rename、copy等文件操作

move_uploaded_file、rename、copy 三个函数的区别&#xff1a; move_uploaded_file 函数是专门用于将通过 HTTP 上传的临时文件移动到指定位置的。如果你想要将一个已经存在的文件移动到另一个位置&#xff0c;而不是上传的文件&#xff0c;那么你应该使用 rename 函数或 co…

Java SPI 机制详解

面向对象设计鼓励模块间基于接口而非具体实现编程&#xff0c;以降低模块间的耦合&#xff0c;遵循依赖倒置原则&#xff0c;并支持开闭原则&#xff08;对扩展开放&#xff0c;对修改封闭&#xff09;。然而&#xff0c;直接依赖具体实现会导致在替换实现时需要修改代码&#…

自动驾驶性能分析时,非常有用的两个信息

自动驾驶的关键路径如下&#xff0c;传感器的数据发送给感知模块&#xff1b;感知模块根据传感器数据来确定车辆所处的环境&#xff0c;比如前方有没有障碍物&#xff0c;是不是和车道线保持着适当的距离等&#xff1b;感知处理之后的数据传递给规控模块&#xff0c;规控根据车…