Opencv (C++)函数库学习整理1,(像素操作,形态学处理)

持续更新中,仅供个人学习(C++的opencv)

图像加载
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(g
alpha + 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
先膨胀后腐蚀
可以填充小的洞,如下图,黑色背景
(个人理解:图像更饱满)

闭操作

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

形态学梯度

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

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

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

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

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

黑帽彩色
上左:原图像 。。。。。。。。。。。上右:输出图像

#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;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值