图像处理 问题笔记

通道

一幅图像,如果关闭了红色通道,那么图像就偏青色。如果关闭了绿色通道,那么图像就偏洋红色。如果关闭了蓝色通道,那么图像就偏黄色。

这个现象再次印证了反转色模型:红色对青色、绿色对洋红色、蓝色对黄色。

如果察看单个通道,发现每个通道都显示为一幅灰度图像(不能说是黑白图像)。某个通道的灰度图像中的明暗对应该通道色的明暗,从而表达出该色光在整体图像上的分布情况。由于通道共有3个,所以也就有了3幅灰度图像。

256种颜色对应256个数码(二进制数值)
也就是2^2 * 2^3 * 2^3 = 2^8 = 256。

8位的意思是:能够显示出来的颜色的数量有8位数
256色模式: 8 bits (B: 2 bits; G: 3 bits; R: 3 bits)。

图像像素的位深度

IPL_DEPTH_8U - 8位无符号整数
IPL_DEPTH_8S - 8位符号整数
IPL_DEPTH_16U - 16位无符号整数
IPL_DEPTH_16S - 16位符号整数
IPL_DEPTH_32S - 32位符号整数
IPL_DEPTH_32F - 单精度浮点数
IPL_DEPTH_64F - 双精度浮点数

CV1的用法,CV2 CV3 已经换为Mat

IplImage* img=cvCreateImage(cvGetSize(image), IPL_DEPTH_8U,3);//此处只是开辟内存

OpenCV 中Resize 和 cvPydown
Resize():将图像精确的转换为目标图像的尺寸,需要用到一些插值方法;

cvPyrdown会失真

canny边缘检测算法:

1.两个阈值是有区别的,高的那个阈值是将要提取轮廓的物体与背景区分开来,就像阈值分割的参数一样,是决定目标与背景对比度的;

低的阈值是用来平滑边缘的轮廓,有时高的阈值设置太大了,可能边缘轮廓不连续或者不够平滑,通过低阈值来平滑轮廓线,或者使不连续的部分连接起来。

Mat_和Mat区别

     在读取矩阵元素时,以及获取矩阵某行的地址时,需要指定数据类型。这样首先需要不停地写“<uchar>”,让人感觉很繁琐,在繁琐和烦躁中容易犯错,如下面代码中的错误,用 at()获取矩阵元素时错误的使用了 double 类型。这种错误不是语法错误,因此在编译时编译器不会提醒。在程序运行时, at()函数获取到的不是期望的(i,j)位置处的元素,数据已经越界,但是运行时也未必会报错。这样的错误使得你的程序忽而看上去正常,忽而弹出“段错误”,特别是在代码规模很大时,难以查错。

      如果使用 Mat_类,那么就可以在变量声明时确定元素的类型, 访问元素时不再需要指定元素类型,即使得代码简洁,又减少了出错的可能性。上面代码可以用 Mat_实现,实现代码如下面例程里的第二个双重 for 循环。

#include <iostream>

#include "opencv2/opencv.hpp"
#include<stdio.h>
using namespace std;
using namespace cv;
int main(int argc,char* argv[])
{
   Mat M(600,800,CV_8UC1);
   for(int i=0;i<M.rows;++i){
   //获取指针时需要指定类型
       uchar *p=M.ptr<uchar>(i);
    for(int j=0;j<M.cols;++j){
         double d1=(double)((i+j)%255);
   //用at读像素时,需要指定类型
         M.at<uchar>(i,j)=d1;
         double d2=M.at<uchar>(i,j);
       }
   }

点操作(点算子)防止溢出

Mat类中的at方法作用:用于获取图像矩阵某点的值或改变某点的值。

对于单通道图像的使用方法:

image.at<uchar>(i,j) = 255;

对于RGB三通道图像的使用方法:

image.at<Vec3b>(i,j)[0] =  255;

   image.at<Vec3b>(i,j)[1] =  255;

   image.at<Vec3b>(i,j)[2] = 255;

Mat::at()取值或改变某点的像素值比较耗时,可以采用Mat的模板子类Mat_

实现对图像矩阵中某个值的获取和改变。

单通道的使用方法:

Mat_<uchar> img = image;

img(i,j) = 255;

三通道RGB的使用方法:

Mat_<Vec3b> img = image;

img(i,j)[0] = 255;

img(i,j)[1] =  255;

img(i,j)[2] =  255;



  //在变量声明时,指定矩阵元素类型
   Mat_<uchar> M1=(Mat_<uchar>&)M;
   for(int i=0;i<M1.rows;++i)
   {
   //不需要指定元素类型,语言简洁
   uchar *p=M1.ptr(i);


       for(int j=0;j<M1.cols;++j){
       double d1=(double)((i+j)%255);
   //直接使用matlab风格的矩阵元素读写,简洁
        M1(i,j)=d1;
        double d2=M1(i,j);
     }
   }
   return 0;
}

OpenCV3之——copyTo()函数的使用方法

定义和用法:
copyTo这个函数有两种定义方式,分别是:

void copyTo( OutputArray m ) const;

void copyTo( OutputArray m, InputArray mask ) const;

也就是参数可以是一张输出图像,或者一张输出图像和一个掩码图。

那么:

image.copyTo(imageROI);

在这里插入图片描述
就是把image这张图复制(copy to)到imageROI上。

image.copyTo(imageROI,mask);

在这里插入图片描述
则是不仅把image这张图复制(copy to)到mageROI上,且image对应mask中像素值为0的像素点都不会贴到imageROI上。
掩膜大小和要贴上去的图大小一致,不然内存报错。

saturate_cast在图像点操作(点算子)里面防止越界

pa.at<Vec3b>(i, j)[c] = saturate_cast<uchar>((g_nContrastValue*0.01)*pa.at<Vec3b>(i, j)[c] + g_nBrightValue);

加了saturate_cast
在这里插入图片描述
没加saturate_cast或者用了简单的强制类型转换

pa.at<Vec3b>(i, j)[c] = ((g_nContrastValue*0.01)*pa.at<Vec3b>(i, j)[c] + g_nBrightValue);

在这里插入图片描述
原理大致是这样:

if(data<0)
        data=0;
else if(data>255)
	data=255;
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页