opencv常用图像处理函数详解(一)

文章目录

      • 1.读取图像(imread)
      • 2.保存图像(imwrite)
      • 3.获取图像像素值大小
      • 4.转换图像色彩
      • 5.叠加两张图像
      • 6.图像二值化

1.读取图像(imread)

Mat cv::imread(const String & filename, int flags = IMREAD_COLOR)	
cv.imread(filename[, flags]) ->	retval
说明:函数imread从指定文件加载图像并将其返回。如果无法读取图像(因为缺少文件、权限不正确、格式不受支持或无效),
		函数将返回一个空矩阵(Mat::data==NULL)。
参数:
	filename 要加载的图像名称(路径)
	flags 图像的加载方式
flag取值 flag含义
IMREAD_UNCHANGED
Python: cv.IMREAD_UNCHANGED
按原样返回加载的图像
IMREAD_GRAYSCALE
Python: cv.IMREAD_GRAYSCALE
始终将图像转换为单通道灰度图像(编解码器内部转换)
IMREAD_COLOR
Python: cv.IMREAD_COLOR
始终将图像转换为3通道BGR彩色图像
IMREAD_ANYDEPTH
Python: cv.IMREAD_ANYDEPTH
当输入具有相应深度时,返回16位/32位图像,否则将其转换为8位
IMREAD_ANYCOLOR
Python: cv.IMREAD_ANYCOLOR
以任何可能的颜色格式读取图像
IMREAD_LOAD_GDAL
Python: cv.IMREAD_LOAD_GDAL
使用gdal驱动程序加载图像
IMREAD_REDUCED_x_y
Python: cv.IMREAD_REDUCED_x_y
始终将图像转换为x图像,图像大小减小1/y(x可以是COLOR或者GRAYSCALE,y可以是2,4,8)
IMREAD_IGNORE_ORIENTATION
Python: cv.IMREAD_IGNORE_ORIENTATION
不根据EXIF的方向标志旋转图像

例程:

#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
	//分别以彩色格式和灰度图格式读取图像
    Mat colorImg = imread("image1.png", IMREAD_COLOR);
    Mat grayImg = imread("image1.png", IMREAD_GRAYSCALE);

	//显示图像
    imshow("colorImg", colorImg);
    imshow("grayImg", grayImg);
    waitKey(0);
    return 0;
}

opencv常用图像处理函数详解(一)_第1张图片

2.保存图像(imwrite)

bool cv::imwrite(const String & filename, InputArray img, const std::vector< int > & params = std::vector< int >())		

cv.imwrite(	filename, img[, params]	) ->retval

说明:数imwrite将图像保存到指定文件。图像格式是根据文件扩展名选择的
参数:
	filename 要保存的图像名称(路径)
	img 要保存的图像
	flags 图像的保存方式

示例:

#include 

using namespace cv;
using namespace std;

static void paintAlphaMat(Mat &mat)
{
    CV_Assert(mat.channels() == 4);
    for (int i = 0; i < mat.rows; ++i)
    {
        for (int j = 0; j < mat.cols; ++j)
        {
            Vec4b& bgra = mat.at<Vec4b>(i, j);
            bgra[0] = UCHAR_MAX; // 固定蓝色颜色值为255
            bgra[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX); // 绿色从左向右变大
            bgra[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX); // 红色从上到下变大
            bgra[3] = saturate_cast<uchar>(0.5 * (bgra[1] + bgra[2])); // 透明度从左上到右下渐渐变大
        }
    }
}

int main()
{
    Mat mat(480, 640, CV_8UC4); // 创建一个带有透明度通道的矩阵
    paintAlphaMat(mat); //在矩阵上绘制图案
    
    //设置压缩率
    vector<int> compression_params;
    compression_params.push_back(IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);
    
    bool result = false;
    try
    {
        result = imwrite("alpha.png", mat, compression_params); //保存图像
    }
    catch (const cv::Exception& ex)
    {
        fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
    }
    if (result)
        printf("Saved PNG file with alpha data.\n");
    else
        printf("ERROR: Can't save PNG file.\n");
    vector<Mat> imgs;
    imgs.push_back(mat);
    imgs.push_back(~mat);
    imgs.push_back(mat(Rect(0, 0, mat.cols / 2, mat.rows / 2)));
    imwrite("test.tiff", imgs);
    printf("Multiple files saved in test.tiff\n");
    return result ? 0 : 1;
}

3.获取图像像素值大小

为了获得像素值大小,必须知道图像的类型和通道数量。

  1. 单通道灰度图像(类型8UC1)和像素坐标x和y时:
    Scalar intensity = img.at<uchar>(y, x);
    //或者
    Scalar intensity = img.at<uchar>(Point(x, y));
    
  2. 三通道彩色图像(类型8UC3)和像素坐标x和y时:
    Vec3b intensity = img.at<Vec3b>(y, x);
    uchar blue = intensity.val[0];
    uchar green = intensity.val[1];
    uchar red = intensity.val[2];
    

4.转换图像色彩

void cv::cvtColor(InputArray src, OutputArray dst, int code, int dstCn = 0 )	
cv.cvtColor(src, code[, dst[, dstCn]]) ->dst
说明:将图像从一种颜色空间转换为另一种颜色。
参数:
	src 输入图像:8位无符号、16位无符号(CV_16UC…)或单精度浮点。
	dst 输出与src大小和深度相同的图像
	code 颜色空间转换码
	dstCn 目的图像中的频道数;如果参数为0,则通道的数量将自动从src和code中导出

示例:

#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
    //分别以彩色格式和灰度图格式读取图像
    Mat colorImg = imread("image1.png", IMREAD_COLOR);
    Mat grayImg;

    //转换为灰度图
    cvtColor(colorImg, grayImg, COLOR_BGR2GRAY);

    //显示图像
    imshow("原始图像", colorImg);
    imshow("转换后的灰度图", grayImg);
    waitKey(0);
    return 0;
}

opencv常用图像处理函数详解(一)_第2张图片

5.叠加两张图像

void cv::addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1 )	
cv.addWeighted(	src1, alpha, src2, beta, gamma[, dst[, dtype]]) ->dst
说明:将图像从一种颜色空间转换为另一种颜色。
参数:
	src1 第一张图像
	alpha 第一张图像所占的比重
	src2 第二张图像,必须与第一张有相同的大小
	beta 第二张图像所占的比重
	gamma 颜色空间转换码
	dst 叠加后的图像
	dtype 输出阵列的可选深度;当两个输入数组具有相同的深度时,dtype可以设置为-1,这相当于src1.depth().

函数addWeighted计算两个数组的加权和,计算方式如下所示:
dst ⁡ ( I ) = s a t u r a t e ( src ⁡ 1 ( I ) ∗ a l p h a + src ⁡ 2 ( I ) ∗ b e t a + g a m m a ) \operatorname{dst}(I)= saturate (\operatorname{src} 1(I) * alpha +\operatorname{src} 2(I) * beta + gamma ) dst(I)=saturate(src1(I)alpha+src2(I)beta+gamma)
其中I是数组元素的多维索引。对于多通道阵列,每个通道都是独立处理的。
示例:

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include 

using namespace cv;
// 这里不使用c++名称空间std,以避免opencv中beta变量和c++17中std::beta之间的冲突

int main( void )
{
   double alpha = 0.5; //第一张图像权重设置
   double beta = 0.5; //第二张图像权重设置

   Mat dst;
   Mat src1 = imread("image1.png"); //读取第一张图像
   Mat src2 = imread("image2.png"); //读取第二张图像

   addWeighted( src1, alpha, src2, beta, 0.0, dst); //叠加两张图像
   imshow( "第一张图像", src1); //显示第一张图像
   imshow( "第二张图像", src2); //显示第二张图像
   imshow( "叠加后的图像", dst ); //显示叠加后的图像
   waitKey(0);
   return 0;
}

6.图像二值化

double cv::threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)	
cv.threshold(src, thresh, maxval, type[, dst]) ->retval, dst
说明:对每个数组元素应用固定阈值处理。
参数:
	src 输入阵列(多通道、8位或32位浮点)
	dst 与src大小、类型和通道数相同的输出数组
	thresh 阈值
	maxval 与THRESH_BINARY和THRESH_INARY_INV阈值类型一起使用的最大值
	type 阈值类型

阈值类型说明:
opencv常用图像处理函数详解(一)_第3张图片
以上面这张图为例,X轴代表图像上某行的数据,y轴代表数据值的大小,蓝色的线代表阈值

  1. Threshold Binary
    该阈值操作可以表示为:
    dst ⁡ ( x , y ) = { maxVal ⁡  if  src ⁡ ( x , y ) > thresh ⁡ 0  otherwise  \operatorname{dst}(x, y)=\left\{\begin{array}{ll}\operatorname{maxVal} & \text { if } \operatorname{src}(x, y)>\operatorname{thresh} \\ 0 & \text { otherwise }\end{array}\right. dst(x,y)={maxVal0 if src(x,y)>thresh otherwise 
    如果像素src(x,y)的强度高于阈值,则将新的像素强度设置为MaxVal。否则,像素设置为0。经过Threshold Binary二值化处理,例图将变为如下所示:
    opencv常用图像处理函数详解(一)_第4张图片

  2. Threshold Binary, Inverted
    该阈值操作可以表示为:
    dst ⁡ ( x , y ) = { 0  if  src ⁡ ( x , y ) > thresh ⁡ maxVal ⁡  otherwise  \operatorname{dst}(x, y)=\left\{\begin{array}{ll}0 & \text { if } \operatorname{src}(x, y)>\operatorname{thresh} \\ \operatorname{maxVal} & \text { otherwise }\end{array}\right. dst(x,y)={0maxVal if src(x,y)>thresh otherwise 
    如果像素src(x,y)的强度高于阈值,则新的像素强度设置为0。否则,设置为MaxVal。经过Threshold Binary, Inverted二值化处理,例图将变为如下所示:
    opencv常用图像处理函数详解(一)_第5张图片

  3. Truncate
    该阈值操作可以表示为:
    dst ⁡ ( x , y ) = { threshold ⁡  if  src ⁡ ( x , y ) > thresh ⁡ src ⁡ ( x , y )  otherwise  \operatorname{dst}(x, y)=\left\{\begin{array}{ll}\operatorname{threshold} & \text { if } \operatorname{src}(x, y)>\operatorname{thresh} \\ \operatorname{src}(x, y) & \text { otherwise }\end{array}\right. dst(x,y)={thresholdsrc(x,y) if src(x,y)>thresh otherwise 
    像素的最大强度值为thresh,如果src(x,y)更大,则其值将被截断。经过Truncate二值化处理,例图将变为如下所示:
    opencv常用图像处理函数详解(一)_第6张图片

  4. Threshold to Zero
    该阈值操作可以表示为:
    dst ⁡ ( x , y ) = { src ⁡ ( x , y )  if  src ⁡ ( x , y ) > thresh ⁡ 0  otherwise  \operatorname{dst}(x, y)=\left\{\begin{array}{ll}\operatorname{src}(x, y) & \text { if } \operatorname{src}(x, y)>\operatorname{thresh} \\ 0 & \text { otherwise }\end{array}\right. dst(x,y)={src(x,y)0 if src(x,y)>thresh otherwise 
    如果src(x,y)低于thresh,则新的像素值将设置为0。经过Threshold to Zero二值化处理,例图将变为如下所示:
    opencv常用图像处理函数详解(一)_第7张图片

  5. Threshold Binary, Inverted
    该阈值操作可以表示为:
    dst ⁡ ( x , y ) = { 0  if  src ⁡ ( x , y ) > thresh ⁡ src ⁡ ( x , y )  otherwise  \operatorname{dst}(x, y)=\left\{\begin{array}{ll}0 & \text { if } \operatorname{src}(x, y)>\operatorname{thresh} \\ \operatorname{src}(x, y) & \text { otherwise }\end{array}\right. dst(x,y)={0src(x,y) if src(x,y)>thresh otherwise 
    如果src(x,y)大于thresh,则新的像素值将设置为0。经过Threshold Binary, Inverted二值化处理,例图将变为如下所示:
    opencv常用图像处理函数详解(一)_第8张图片
    例程:

#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include 

using namespace cv;
using std::cout;

int threshold_value = 0; //阈值
int threshold_type = 3; //阈值类型
int const max_value = 255; //最大值滚动条最大值
int const max_type = 4; //阈值类型滚动条最大值
int const max_binary_value = 255; //图像最大值

Mat src, src_gray, dst; //图像

//窗口信息变量
const char* window_name = "Threshold Demo";
const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted";
const char* trackbar_value = "Value";

static void Threshold_Demo( int, void* )
{
    /* 0: Binary
     1: Binary Inverted
     2: Threshold Truncated
     3: Threshold to Zero
     4: Threshold to Zero Inverted
    */
    threshold( src_gray, dst, threshold_value, max_binary_value, threshold_type ); //度图像进行二值化处理
    imshow( window_name, dst ); //显示最终二值化的结果
}

int main( int argc, char** argv )
{
    String imageName("image1.png"); // 图像的名称

    src = imread( samples::findFile( imageName ), IMREAD_COLOR ); // 读取图像
    
    if (src.empty()) //判断图像是否读取成功
    {
        cout << "Cannot read the image: " << imageName << std::endl;
        return -1;
    }
    
    cvtColor( src, src_gray, COLOR_BGR2GRAY ); // 将彩色图转换为灰度图
    namedWindow( window_name, WINDOW_AUTOSIZE ); // 创建窗口用来显示结果图像
    //创建阈值类型选择滚动条
    createTrackbar( trackbar_type,
                    window_name, &threshold_type,
                    max_type, Threshold_Demo );
    //创建阈值大小选择滚动条
    createTrackbar( trackbar_value,
                    window_name, &threshold_value,
                    max_value, Threshold_Demo );
    Threshold_Demo( 0, 0 ); // 调用阈值处理函数
    waitKey(); //等待按键响应结束程序
    return 0;
}

opencv常用图像处理函数详解(一)_第9张图片

你可能感兴趣的:(opencv,opencv)