图像加载

Max src = imread(‘adsfaasdf’)

判断图像是否空

src.empyt() = ture or false
 src.data

图像框

nameWindow(‘aaa’, CV_WINDOW_AUTOSIZE) 或CV_WINDOW_NORMAL

图像展示

imshow(‘aaa’, src)

修改图像

(改变颜色空间rgb )
 cvtColor(src, dst, CV_BGR2GRAY)

保存图像

imwrite(‘image/aaa.jpg’, src)

像素矩阵指针

Mat.ptr(int i=0) ,i表示第几行
 获得当前行指针 const uchar* current = my.Image.ptr(row)

像素范围处理

saturate_cast(i)
 i < 0 , 返回0;
 0 < i < 255, 返回 i;
 i > 255 , 返回255;

像素掩模 mask

int rows = src.rows;
 int cols=(src.cols-1) * src.channels();一个增加对比度的掩模
 [ 0 , -1 , 0;
 -1 , 5 , -1;
 0 , -1 , 0 ]

图像大小复制

dst = Mat::zeros(src.size(),src.type());

掩模函数

Mat kernel = ( Mat_(3,3) << 0 , -1 , 0 , -1 , 5 , -1 , 0 , -1 , 0 ) ;
 filter2D(src , dst , src.depth(), kernel)
 src.depth() : 8位,24位,32位 , -1也行

获取执行时间:

double t = getTickCount() ;

Mat 与 IplImage

Mat 是Opecv2.0后引进,不存在内存泄漏的问题
 IplImage 是2001年OpenCV发布后一直存在,存在内存泄漏的问题Mat 常用方法
 void copyTo( Mat mat)
 src.copyTo()void convertTo(mat dst, int type) 类型转换
Max clone()
 src.clone()int channels() 通道数
 int depth() 位深度
 bool empty()
 uchar* ptr(i=0)

颜色赋值

Scalar(double, double, double)
 三个double分别代表B G R

Mat对象创建

cv::Mat::Mat
 Mat M ( 2, 2, CV_8UC3, Scalar(0,0,255))Mat m1;
 m1.create(src.size(), src.type());
 m1 = Scalar(0, 0, 255);Mat m2 = Mat::zeros( src.size(), src.type())
 Mat m2 = Mat::eye(2 , 2 , 8UC1)

Mat 对象使用

1 部分复制 ( 只复制头,指针 , 不会复制数据部分 )
 Mat A = imread ( imgFilePath )
 Mat B ( A ) 拷贝构造函数
 2 完全复制
 Mat F = A.clone()
 Mat G; A.copyTo(G);

指针指向对应像素点,并修改对应像素值

int gray = src.at(row, col)
 src.at(row, col) = 255 -gray

RGB图像

float b = src.at (row, col ) [0];
 float g = src.at (row, col ) [1];
 float r = src.at (row, col ) [2];
 dst.at (row, col ) [0] = stturate_cast(balpha + beta);
 dst.at (row, col ) [1] = stturate_cast(galpha + beta);
 dst.at (row, col ) [2] = stturate_cast(r*alpha + beta);

位操作,全部去反

bitwise_not(src, dst);

两图像先行混合函数:

cv::addWeighted( src1, alpha, src2, beta, gamma, dst)
 注:确保 类型,大小一致

画点

cv::Point
 Point p;
 p.x = 10;
 p.y = 8;
 or
 p = Point(10,8);

元素向量

cv::Scalar
 Scalar color = Scalar(0, 0, 255); // 红色
 Scalar(a, b, c); // a = blue, b = green, c = red 表示RGB三个通道

绘制线,矩形,圆,椭圆等几何形状
线

cv::Line
 Point p1 = Point(20,30); //点1
 Point p2 = Point(400,400); //点2
 Scalar color = Scalar(255, 0, 0); //设置颜色
 cv::Line(src, p1, , p2, color , 2 (thickness), LINE_8 (linetype) )

椭圆

cv::ellipse
 ellipse(src, Point(src.cols/2,src.rows/2) , Size(src.cols/4,src.rows/8)(长短), 90(倾斜角度) , 0 , 360(0-360画满), color , 2(thickness), LINE_8)

矩形

Rect rect = Rect(x, y, width, height); //画形状
 Scalar color = Scalar(255, 0, 0); //设置颜色
 cv::rectangle(src, rect, , color, 2 (thickness), LINE_8 (linetype) )

cv::circle
 Scalar color = Scalar(255, 0, 0); //设置颜色
 Point center = Point(src.cols/2,src.rows/2);//中心
 cv::circle(src, center, 150(半径), color, 2, LINE_8)

多边形填充

cv::fillPoly
 Point pts[1][5];
 pts[0][0] = Point(100,100);
 pts[0][1] = Point(100,200);
 pts[0][2] = Point(200,200);
 pts[0][3] = Point(200,100);
 pts[0][4] = Point(100,100);const Point* ppts[] = [pts[0]];
 int npt[] = [5]; //个数
 Scalar color = Scalar(255, 255, 12); //设置颜色
 fillPoly(src, ppts, npt, 1, color, 8);//填充 cv::fillPoly

加文本text

putText(src, “Hello World”, Point (300, 300), CV_FONT_HERSHEY_COMPLEX(字体), 1.0,Scalar(0,0,255),1,8)

画随机的线 / RNG (随机数库)

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

//先声明
void RandomlineDemo(Mat);

int main(){
    Mat bgImage = imread("D:/timg.jpg");
    RandomlineDemo(bgImage);
}

//再定义
void RandomlineDemo(Mat bgImage){
    RNG rng(12345);
    Point pt1;
    Point pt2;
    Mat bg = Mat::zeros(bgImage.size(), bgImage.type());
    namedWindow("random line demo", CV_WINDOW_AUTOSIZE);
    for (int i = 0; i<10000; i++){
        pt1.x = rng.uniform(0, bg.cols);
        pt2.x = rng.uniform(0, bg.cols);
        pt1.y = rng.uniform(0, bg.rows);
        pt2.y = rng.uniform(0, bg.rows);
        Scalar color = Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255) );
        if (waitKey(50) > 0)
            break;
        line(bg, pt1, pt2, color, 1, 8);
        imshow("random line demo", bg);
    }
}

图像模糊

均值模糊

(模板内权重一样的模糊)
 blur(Mat src, Mat dst, Size(xradius, yradius),Point(-1,-1)(默认中心));

高斯模糊

(是一个抛物线的基于权重的模糊)
 GaussianBlur(Mat src, Mat dst, Size(x, y),sigmaX, sigmaY);
 Size(x, y) 必须是奇数

图像腐蚀与膨胀

膨胀:
 需要图像A 和 结构元素B,
 图像A 和 结构元素B,对应位置进行与运算,决定该像素位置的0或1是否保留
 (结构元素B 在 图像A上移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值来替代锚点的像素,B为任意形状)
 腐蚀相反

获取结构形状

getStructuringElement( int shape, Size ksize, Point anchor)
 -形状(MORPH_RECT / MORPH_CROSS / MORPH_ELLIPSE)
 -大小
 -锚点 Point(-1, -1) 默认中心腐蚀
 erode( src, dst, kernel )膨胀
 dliate( src, dst, kernel )

动态调整结构元素大小

TrackBar createTrackbar( const String & tr ackbarname, const String winName, int* value, int count, Trackbarcallback func, void * userdata = 0)

下面代码生成图像+调整条(手动调整结构元素大小)

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;

Mat src, dst;
char OUTPUT_WIN[] = "output image";
int element_size = 3;
int max_size = 21;
void CallBack_Demo(int , void*);
//int main( int argc, char** argv) {
int main() {
    src = imread("D:/timg.jpg");
    if (!src.data) {
        printf("could not load image... \n");
        return -1;
    }
    namedWindow("input image", CV_WINDOW_AUTOSIZE);
    imshow("input image", src);

    namedWindow(OUTPUT_WIN, CV_WINDOW_AUTOSIZE);
    createTrackbar("Element Size :" , OUTPUT_WIN, &element_size, max_size, CallBack_Demo);
    CallBack_Demo(0,0);
    waitKey(0);
    return 0;
}

void CallBack_Demo(int, void*){
    int s = element_size * 2 + 1;
    Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));
    dilate(src, dst, structureElement, Point(-1, -1), 1);

    imshow(OUTPUT_WIN, dst);
    return;
}

开 / 闭操作
开操作 - open
先腐蚀后膨胀 ,去掉小的对象,
假设背景黑色,有白色小点(白色小点消失)
(个人理解:图像去除毛刺)

相关API

morphologyEx( src, dest, CV_MOP_BLACKHAT, kernel );
 int OPT – CV_MOP_OPEN/ CV_MOP_CLOSE/ CV_MOP_GRADIENT/ CV_MOP_TOPHAT/ CV_MOP_BLACKHAT 形态学操作类型
 Mat kernel 结构元素
 int Iteration 迭代次数,默认是1

闭操作 - close
先膨胀后腐蚀
可以填充小的洞,如下图,黑色背景
(个人理解:图像更饱满)

opencv库中填充_opencv

形态学梯度 - Morphological Gradient
膨胀减去腐蚀
又称基本梯度(其他还包括-内部梯度,方向梯度)

opencv库中填充_opencv库中填充_02

基本梯度:是用膨胀后的图像减去腐蚀后的图像得到差值图像,称为梯度图像也是OpenCV中支持的计算形态学梯度的方法,而此方法得到梯度有被称为基本梯度。
内部梯度:是用原图像减去腐蚀之后的图像得到差值图像,称为图像的内部梯度。
外部梯度:是用图像膨胀之后再减去原来的图像得到的差值图像,称为图像的外部梯度。
方向梯度:是使用X方向与Y方向的直线作为结构元素之后得到图像梯度,用X方向直线做结构元素分别膨胀与腐蚀之后得到图像求差值之后称为X方向梯度,用Y方向直线做结构元素分别膨胀与腐蚀之后得到图像求差值之后称为Y方向梯度。

顶帽 - top hat
原图像与开操作之间的差值图像

opencv库中填充_opencv库中填充_03


上左:原图像 。。。。。。。 上右:输出图像

黑帽
闭操作与原图像之间的差值图像

opencv库中填充_opencv库中填充_04


上左:原图像 。。。。。。。 上右:输出图像

opencv库中填充_计算机视觉_05


上左:原图像 。。。。。。。。。。。上右:输出图像

#include <iostream>
#include <opencv2/opencv.hpp>
#include <cmath>

using namespace cv;

int main (){
    Mat src, dst;
    src = imread("D:/cat.jpg");
    if (!src.data){
        printf("could not load image...\n");
    }
    namedWindow("input image", CV_WINDOW_AUTOSIZE);
    imshow("input image", src);
    char output_title[] = "morphology demo";
    namedWindow(output_title, CV_WINDOW_AUTOSIZE);

    Mat kernel = getStructuringElement(MORPH_RECT, Size(40,40), Point(-1,-1));
//    morphologyEx(src, dst, CV_MOP_OPEN, kernel);
//    morphologyEx(src, dst, CV_MOP_GRADIENT, kernel);
//    morphologyEx(src, dst, CV_MOP_TOPHAT, kernel);
    morphologyEx(src, dst, CV_MOP_BLACKHAT, kernel);
    imshow(output_title, dst);
    waitKey(0);

    return 0;
}