opencv入门基础(c++)

  • 七.绘制形状与文字
    • 7.1使用cv::Point与cv::Scalar
    • 7.2绘制线、矩形、园、椭圆等基本几何形状
      • 绘制线
      • 绘制矩形
      • 绘制椭圆
      • 绘制圆
      • 绘制填充图形
    • 7.3绘制文字
    • 7.4随机数生成cv::RNG
  • 八、模糊图像一
    • 8.1模糊原理
    • 8.2相关API
      • 均值模糊
      • 高斯模糊
  • 九、图像模糊二
    • 9.1中值滤波
    • 9.2双边滤波
    • 9.3相关API
  • 十、膨胀与腐蚀
    • 10.1形态学操作(morphology operators)-膨胀
    • 10.2形态学操作-腐蚀
    • 10.3相关API
    • 10.4动态调整结构元素大小
  • 十一、形态学操作
    • 11.1开操作- open
    • 11.2闭操作-close
    • 11.3形态学梯度- Morphological Gradient
    • 11.4顶帽 – top hat
    • 11.5黑帽
    • 11.6相关API
  • 十二、形态学操作应用-提取水平与垂直线
    • 12.1原理方法
      • 二值图像与灰度图像上的膨胀操作
      • 二值图像与灰度图像上的腐蚀操作
    • 12.2结构元素
    • 12.3提取步骤
      • 转换为二值图像 – adaptiveThreshold
      • 定义结构元素
      • 后处理

七.绘制形状与文字

使用cv::Point与cv::Scalar
绘制线、矩形、园、椭圆等基本几何形状
随机生成与绘制文本

7.1使用cv::Point与cv::Scalar

Point表示2D平面上一个点x,y
Point p;
p.x = 10;
p.y = 8;
or
p = Pont(10,8);
Scalar表示四个元素的向量
Scalar(a, b, c);// a = blue, b = green, c = red表示RGB三个通道

7.2绘制线、矩形、园、椭圆等基本几何形状

画线 cv::line (LINE_4\LINE_8\LINE_AA)【LINE_AA反锯齿-画圆】
画椭圆cv::ellipse
画矩形cv::rectangle 画矩形Rect(x,y,width,height)
画圆cv::circle
ellipse(Mat img,Point(x,y),Size(a,b),angle,0,360,Scalar(,,),thickness,lineType);
画填充cv::fillPoly

绘制线

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;
void Myline();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}Myline();char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}void Myline() {Point p1 = Point(20, 30);//位置坐标Point p2;p2.x = 300;p2.y = 300;Scalar color = Scalar(0, 0, 255);line(src1, p1, p2, color, 1, LINE_8);
}

绘制矩形

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;void MyRectangle();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}MyRectangle();char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}void MyRectangle() {Rect rect = Rect(200, 50, 200, 200);Scalar color = Scalar(0, 0, 225);rectangle(src1, rect, color, 2, LINE_8);
}

绘制椭圆

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;
void MyOval();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}MyOval();char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}void MyOval() {Scalar color = Scalar(0, 250, 0);ellipse(src1, Point(src1.cols / 2, src1.rows / 2), Point(src1.cols / 6, src1.rows / 7), 45, 0, 360, color, 2, LINE_8);
}

绘制圆

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;
void MyCircle();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}MyCircle();char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}void MyCircle() {Scalar color = Scalar(130, 0, 0);circle(src1, Point(src1.cols / 2, src1.rows / 2), 100, color, 2, LINE_8);
}

绘制填充图形

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;
void MyCircle();
void MyPolygon();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}MyCircle();MyPolygon();char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}void MyCircle() {Scalar color = Scalar(130, 0, 0);circle(src1, Point(src1.cols / 2, src1.rows / 2), 100, color, 2, LINE_8);
}
void MyPolygon() {Scalar color = Scalar(250, 0, 0);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 };fillPoly(src1, ppts, npt, 1, color, 8);}

7.3绘制文字

putText函数 中设置fontFace(cv::HersheyFonts),

  • fontFace, CV_FONT_HERSHEY_PLAIN
  • fontScale , 1.0, 2.0~ 8.0
#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}putText(src1, "hhhhhhhhhhhhhhhh",Point(300,300), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 4, 8);/*注释在src1图片上,显示hhhhhhhhhhhhhhhh,位置在(300,300),字体类型为FONT_HERSHEY_SIMPLEX,字体大小为2,颜色为红色,字体厚度为4,线型默认为8.*/char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

7.4随机数生成cv::RNG

生成高斯随机数gaussian (double sigma)
生成正态分布随机数uniform (int a, int b)

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1;
void RandomLineDemo();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}putText(src1, "hhhhhhhhhhhhhhhh",Point(300,300), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 4, 8);/*注释在src1图片上,显示hhhhhhhhhhhhhhhh,位置在(300,300),字体类型为FONT_HERSHEY_SIMPLEX,字体大小为2,颜色为红色,字体厚度为4,线型默认为8.*/char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);RandomLineDemo();waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}
void RandomLineDemo() {RNG rng(12345);Point pt1;Point pt2;Mat bg = Mat::zeros(src1.size(), src1.type());namedWindow("random line demo", WINDOW_AUTOSIZE);for (int i = 0; i < 100000; i++) {pt1.x = rng.uniform(0, src1.cols);pt2.x = rng.uniform(0, src1.cols);pt1.y = rng.uniform(0, src1.rows);pt2.y = rng.uniform(0, src1.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);}
}

八、模糊图像一

8.1模糊原理

Smooth/Blur 是图像处理中最简单和常用的操作之一
使用该操作的原因之一就为了给图像预处理时候减低噪声
使用Smooth/Blur操作其背后是数学的卷积计算

通常这些卷积算子计算都是线性操作,所以又叫线性滤波


假设有6x6的图像像素点矩阵。

卷积过程:6x6上面是个3x3的窗口,从左向右,从上向下移动,黄色的每个像个像素点值之和取平均值赋给中心红色像素作为它卷积处理之后新的像素值。每次移动一个像素格。

归一化盒子滤波(均值滤波

高斯滤波

8.2相关API

均值模糊

- blur(Mat src, Mat dst, Size(xradius, yradius), Point(-1,-1));//Point(-1,-1))不要去改

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;
void RandomLineDemo();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);blur(src1, dst, Size(15, 15), Point(-1, -1));//均值模糊char output_win[] = "output image";namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

高斯模糊

- GaussianBlur(Mat src, Mat dst, Size(11, 11), sigmax, sigmay);

其中Size(x, y), x, y 必须是正数而且是奇数
sigmax, sigmay:横波和滤波的大小;
Ksize为高斯滤波器模板大小

计算高斯卷积核

#include "iostream"
#include "math.h"using namespace std;
//using namespace cv;//******************高斯卷积核生成函数*************************
//第一个参数gaus是一个指向含有3个double类型数组的指针;
//第二个参数size是高斯卷积核的尺寸大小;
//第三个参数sigma是卷积核的标准差
//*************************************************************
void GetGaussianKernel(double **gaus, const int size, const double sigma);int main(int argc, char *argv[])
{int size = 5; //定义卷积核大小double **gaus = new double *[size];for (int i = 0; i < size; i++){gaus[i] = new double[size];  //动态生成矩阵}cout << "尺寸 = 3*3,Sigma = 1,高斯卷积核参数为:" << endl;GetGaussianKernel(gaus, 3, 1); //生成3*3 大小高斯卷积核,Sigma=1; cout << "尺寸 = 5*5,Sigma =1,高斯卷积核参数为:" << endl;GetGaussianKernel(gaus, 5, 1); //生成5*5 大小高斯卷积核,Sigma=1;cout << "尺寸 = 5*5,Sigma =5,高斯卷积核参数为:" << endl;GetGaussianKernel(gaus, 5, 5); //生成5*5 大小高斯卷积核,Sigma=1;cout << "尺寸 = 5*5,Sigma =7,高斯卷积核参数为:" << endl;GetGaussianKernel(gaus, 5, 7); //生成5*5 大小高斯卷积核,Sigma=1;system("pause");return 0;
}//******************高斯卷积核生成函数*************************
void GetGaussianKernel(double **gaus, const int size, const double sigma)
{const double PI = 4.0*atan(1.0); //圆周率π赋值int center = size / 2;double sum = 0;for (int i = 0; i < size; i++){for (int j = 0; j < size; j++){gaus[i][j] = (1 / (2 * PI*sigma*sigma))*exp(-((i - center)*(i - center) + (j - center)*(j - center)) / (2 * sigma*sigma));sum += gaus[i][j];}}for (int i = 0; i < size; i++){for (int j = 0; j < size; j++){gaus[i][j] /= sum;cout << gaus[i][j] << "  ";}cout << endl << endl;}return;
}
#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;
void RandomLineDemo();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);//blur(src1, dst, Size(15, 15), Point(-1, -1));GaussianBlur(src1,dst, Size(5, 5), 10, 10);char output_win[] = "output image";namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

九、图像模糊二

9.1中值滤波

统计排序滤波器
中值对椒盐噪声有很好的抑制作用

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;
void RandomLineDemo();
int main()
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);//blur(src1, dst, Size(15, 15), Point(-1, -1));//GaussianBlur(src1,dst, Size(5, 5), 10, 10);medianBlur( src1, dst, 5);char output_win[] = "output image";namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

9.2双边滤波

均值模糊无法克服边缘像素信息丢失缺陷。原因是均值滤波是基于平均权重

高斯模糊部分克服了该缺陷,但是无法完全避免,因为没有考虑像素值的不同

高斯双边模糊 – 是边缘保留的滤波方法,避免了边缘信息丢失,保留了图像轮廓不变

#include <opencv2/opencv.hpp>
#include<iostream>
#include<math.h>//using namespace std;
//using namespace cv;void RandomLineDemo();
int main()
{cv::Mat src1, dst;src1 = cv::imread("C:/Users/Admin/Desktop/1.png");    //读取图片(使用图片的绝对路径)if (src1.empty()) {printf("could not find the image!\n");return -1;}//char input_win[] = "input image";cv::namedWindow("input_win",cv:: WINDOW_AUTOSIZE);imshow("input_win", src1);//blur(src1, dst, Size(3, 3), Point(-1, -1));//均值滤波//GaussianBlur(src1,dst, Size(15, 15), 1, 1);//高斯滤波//medianBlur( src1, dst, 5);//中值滤波//bilateralFilter(src1, dst, 15, 70, 3);//双边滤波char output_win[] = "output image";cv::namedWindow(output_win, cv::WINDOW_AUTOSIZE);imshow(output_win, dst);cv::waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

9.3相关API

中值模糊
medianBlur(Mat src, Mat dest, ksize)
双边模糊
bilateralFilter(src, dest, d=15, 150, 3);

15 –计算的半径,半径之内的像数都会被纳入计算,如果提供-1 则根据sigma space参数取值
150 – sigma color 决定多少差值之内的像素会被计算
3 – sigma space 如果d的值大于0则声明无效,否则根据它来计算d值
中值模糊的ksize大小必须是大于1而且必须是奇数。

十、膨胀与腐蚀

10.1形态学操作(morphology operators)-膨胀

图像形态学操作 – 基于形状的一系列图像处理操作的合集,主要是基于集合论基础上的形态学数学
形态学有四个基本操作:腐蚀、膨胀、开、闭
膨胀与腐蚀是图像处理中最常用的形态学操作手段

跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状

白色膨胀,人物变小

10.2形态学操作-腐蚀

腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值
人物腐蚀背景变大

10.3相关API

getStructuringElement(int shape, Size ksize, Point anchor)

  • 形状 (MORPH_RECT \MORPH_CROSS \MORPH_ELLIPSE)
  • 大小
  • 锚点 默认是Point(-1, -1)意思就是中心像素
    dilate(src, dst, kernel)

erode(src, dst, kernel)

10.4动态调整结构元素大小

TrackBar – createTrackbar(const String & trackbarname, const String winName, int* value, int count, Trackbarcallback func, void* userdata=0)
其中最中要的是 callback 函数功能。如果设置为NULL就是说只有值update,但是不会调用callback的函数。

#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) {src = imread("D:/vcprojects/images/test1.png");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);erode(src, dst, structureElement);imshow(OUTPUT_WIN, dst);return;
}

十一、形态学操作

11.1开操作- open

先腐蚀后膨胀

可以去掉小的对象,假设对象是前景色,背景是黑色

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;char output_win[] = "output image";
int main(int argc, char** argv)
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径) if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 30), Point(-1, -1));morphologyEx(src1, dst, MORPH_OPEN, kernel);namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);//imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

11.2闭操作-close

先膨胀后腐蚀(bin2)

可以填充小的洞(fill hole),假设对象是前景色,背景是黑色

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;char output_win[] = "output image";
int main(int argc, char** argv)
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径) if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 30), Point(-1, -1));morphologyEx(src1, dst, MORPH_CLOSE, kernel);namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);//imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

11.3形态学梯度- Morphological Gradient

膨胀减去腐蚀

又称为基本梯度(其它还包括-内部梯度、方向梯度)

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;char output_win[] = "output image";
int main(int argc, char** argv)
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径) if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 30), Point(-1, -1));morphologyEx(src1, dst, MORPH_GRADIENT, kernel);namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);//imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

11.4顶帽 – top hat

顶帽 是原图像与开操作之间的差值图像

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;char output_win[] = "output image";
int main(int argc, char** argv)
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径) if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 30), Point(-1, -1));morphologyEx(src1, dst, MORPH_TOPHAT, kernel);namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);//imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

11.5黑帽

黑帽是闭操作图像与源图像的差值图像

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;char output_win[] = "output image";
int main(int argc, char** argv)
{src1 = imread("C:/Users/Admin/Desktop/1.jpg");  //读取图片(使用图片的绝对路径) if (src1.empty()) {printf("could not find the image!\n");return -1;}char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win, src1);Mat kernel = getStructuringElement(MORPH_RECT, Size(30, 30), Point(-1, -1));morphologyEx(src1, dst, MORPH_BLACKHAT, kernel);namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, dst);//imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}

11.6相关API

morphologyEx(src, dest, CV_MOP_BLACKHAT, kernel);

  • Mat src – 输入图像

  • Mat dest – 输出结果

  • int OPT
    MORPH_OPEN – 开运算
    MORPH_CLOSE – 闭运算
    MORPH_GRADIENT - 形态学梯度
    MORPH_TOPHAT - 顶帽
    MORPH_BLACKHAT - 黑帽

  • Mat kernel 结构元素

  • int Iteration 迭代次数,默认是1

十二、形态学操作应用-提取水平与垂直线

12.1原理方法

图像形态学操作时候,可以通过自定义的结构元素实现结构元素
对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏
感的对象改变而不敏感的对象保留输出。通过使用两个最基本的
形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像
的操作、得到想要的结果。

  • 膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值
  • 腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

二值图像与灰度图像上的膨胀操作

二值图像与灰度图像上的腐蚀操作

12.2结构元素

上述膨胀与腐蚀过程可以使用任意的结构元素
常见的形状:矩形、园、直线、磁盘形状、砖石形状等各种自定义形状

12.3提取步骤

输入图像彩色图像 imread
转换为灰度图像 – cvtColor
转换为二值图像 – adaptiveThreshold
定义结构元素
开操作 (腐蚀+膨胀)提取 水平与垂直线

转换为二值图像 – adaptiveThreshold

adaptiveThreshold(
Mat src, // 输入的灰度图像
Mat dest, // 二值图像
double maxValue, // 二值图像最大值
int adaptiveMethod // 自适应方法,只能其中之一 –
// ADAPTIVE_THRESH_MEAN_C , ADAPTIVE_THRESH_GAUSSIAN_C
int thresholdType,// 阈值类型
int blockSize, // 块大小
double C // 常量C 可以是正数,0,负数
)


定义结构元素

一个像素宽的水平线 - 水平长度 width/30
一个像素宽的垂直线 – 垂直长度 height/30

后处理

bitwise_not(Mat bin, Mat dst)像素取反操作,255 – SrcPixel
模糊(blur)

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include<iostream>
#include<math.h>
using namespace std;
using namespace cv;
Mat src1,dst;char output_win[] = "output image";
int main(int argc, char** argv)
{    /*第一步:imread导入彩色图像*/src1 = imread("C:/Users/Admin/Desktop/1.jpg");   //读取图片(使用图片的绝对路径) if (src1.empty()) {printf("could not find the image!\n");return -1;}/*第二步:转为灰度图像cvtColor(src1, dst, COLOR_BGR2GRAY);*/if (src1.channels() == 1) {dst = src1;}else {cvtColor(src1, dst, COLOR_BGR2GRAY);}/*第三步:转为二值图像*/Mat binImg;adaptiveThreshold(dst, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);/*第四步:定义结构元素*/// 水平结构元素Mat hline = getStructuringElement(MORPH_RECT, Size(src1.cols / 16, 1), Point(-1, -1));// 垂直结构元素Mat vline = getStructuringElement(MORPH_RECT, Size(1, src1.rows / 16), Point(-1, -1));// 矩形结构Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));/*第五步:开操作 (腐蚀+膨胀)提取 水平与垂直线*/Mat temp;erode(binImg, temp, vline);dilate(temp, dst, vline);/*第六步:一些可有可无的后处理*/bitwise_not(dst, dst);//像素取反操作blur(dst, dst, Size(3, 3), Point(-1, -1));//模糊char input_win[] = "input image";namedWindow(input_win, WINDOW_AUTOSIZE);imshow(input_win,dst);namedWindow(output_win, WINDOW_AUTOSIZE);imshow(output_win, binImg);//imshow(output_win, dst);waitKey(0);//不加此语句图片会一闪而过system("path");getchar();return 0;
}}

opencv入门基础(c++)【二】相关推荐

  1. OpenCV入门基础操作(二)----图像像素的处理

    OpenCV入门基础操作(二)----图像像素的处理 像素处理 读取一个图像像素 修改像素值 代码案例 像素处理 读取一个图像像素 在读取图像的时候一般要用到如下的命令: 返回值=图像(位置参数), ...

  2. opencv入门基础(七)基于dlib进行本地图片、实时人脸检测

    opencv入门基础(七)基于dlib进行本地图片.实时人脸检测 一.背景知识 1.Dlib是一个深度学习开源工具,基于C++开发,也支持Python开发接口. 2.由于Dlib对于人脸特征提取效果很 ...

  3. 【AI白身境】搞计算机视觉必备的OpenCV入门基础

    文章首发于微信公众号<有三AI> [AI白身境]搞计算机视觉必备的OpenCV入门基础 今天是新专栏<AI白身境>的第五篇. 曾经看过一个视频,树莓派自平衡机器人自动追着小球跑 ...

  4. Games101计算机图形学入门基础之二:光栅化

    Games101计算机图形学入门基础之二:光栅化 引言 三角形的离散化 采样 走样 走样带来的瑕疵 反走样 先模糊再采样 傅里叶变换 低通滤波 卷积 多重采样抗锯齿(超采样) 深度缓存 可见性与遮挡( ...

  5. 【深度学习入门基础】二、简单理解 Transformer

    [深度学习入门基础]二.简单理解 Transformer 文章目录 [深度学习入门基础]二.简单理解 Transformer 自注意力层 多头注意力 Transformer 输入(输出)嵌入 位置编码 ...

  6. vue实战入门基础篇二:从零开始仿门户网站实例-开发框架搭建

    上一篇:vue实战入门基础篇一:从零开始仿门户网站实例-前期准备工作 vue实战入门基础篇二:从零开始仿门户网-2022-2-23 21:00:27 一.目录 第一篇:前期准备工作 第二篇:开发框架搭 ...

  7. opencv mat初始化_【OpenCV入门之十二】看起来一样的图像竟然存在这么大的差别!...

    小白导读 学习计算机视觉最重要的能力应该就是编程了,为了帮助小伙伴尽快入门计算机视觉,小白准备了[OpenCV入门]系列.新的一年文章的内容进行了很大的完善,主要是借鉴了更多大神的文章,希望让小伙伴更 ...

  8. 「AI白身境」搞计算机视觉必备的OpenCV入门基础

    https://www.toutiao.com/a6694013504078217741/ 曾经看过一个视频,树莓派自平衡机器人自动追着小球跑.不经让我脑子蹦出一个有趣的想法,可以做一个识别猫的机器人 ...

  9. opencv入门基础——图像读取,图像显示,图像保存

    一,图像读取 如上图所示,从文件中导入图像用这个函数 retval=cv.imread(文件名,[,显示控制参数]) 显示控制参数,主要是这几个: cv.IMREAD_UNCHANGED cv.IMR ...

最新文章

  1. linux系统编程需要什么,若想成为一名Linux下编程高手,必须能对各种系统调用有透彻的了解...
  2. How to go between HK and Shenzhen (Futian)?
  3. 在VS.NET2003中无法新建C#项
  4. 简明Vim练级攻略(转)
  5. oracle select 行数据_【赵强老师】什么是Oracle的数据字典?
  6. 雷赛运动控制卡能不能用c语言_基于PMAC控制卡的三坐标测量机控制系统
  7. cron每2天跑一次_直购直测,进口新极光每2年或34000公里才需要保养一次?
  8. centos下使用yum命令安装php mcrypt扩展
  9. 普通人买得到国债吗?
  10. Nuget如何管理本地的包
  11. 计算机绘图设备cmy,《计算机图形学》练习测试题库
  12. 【Python数据分析】数据挖掘建模——分类与预测算法评价(含ROC曲线、F1等指标的解释)
  13. Java IP地址解析工具ip2region
  14. 《 极秀校园行Windows XP SP3装机专版 》 光盘介绍
  15. 电压驻波比,回波损耗,传输损耗,电压反射系数,功率传输,功率反射换算表
  16. Android-Hybrid-问题收集Android客户端无法拦截Vue路由的问题
  17. c/c++判断数组中元素的个数
  18. UI设计 调色板的应用
  19. tar 命令压缩时报错 tar: Removing leading `/' from member names
  20. 企业动画宣传片制作要点解析

热门文章

  1. OKEx徐坤:Filecoin的机遇与风险 | 星际崛起IPFS云峰会
  2. 【​观察】揭露迅雷“内讧”闹剧真相 制度性反腐依旧任重道远
  3. C1071: 在注释中遇到意外的文件结束
  4. NFT+DAO,改变流行IP难以融合的制胜法宝
  5. 字符串匹配算法:Horspool算法
  6. html5 video speed control插件,HTML5 Video Speed Control 1.34
  7. eav模型 java_计算和过滤分面类型(EAV)过滤器中的产品/实体
  8. 超级产品:半导体之父,56岁创业,如今年利润能买下1.6个华为
  9. 【精选合集】超强、超全三折页素材模板大合集,精选优质,设计摸鱼素材
  10. 冀欧速 OSA-3S 温湿度传感器