opencv入门

Opencv

1,opencv4环境配置与搭建

版本opencv4.4 + vs2015 64 + win10

Visual studio 2015

新建 Win32控制台程序-> 空项目 -> Release

视图 -> 其他窗口 -> 属性管理器 -> vc++目录配置包含目录和库目录/链接器配置opencv_world440.lib

添加path环境变量opencv-4.4.0\opencv\build\x64\vc14\bin

重启vs

2,新建项目,引入头文件,重新生成解决方案

#include

#include

using namespace cv;

using namespace std;

Int main() {

Mat src = imread(“xxx”, IMREAD_GRAYSCALE);

If(src.empty()) {

printf(“xxx\n”);

Return -1;

}

namedWindow(“aaa”, WINDOW_FREERATIO);

Imshow(“aaa”, src);

waitKey(0);

return 0;

}

3,opecv函数

1.色彩空间转换函数- cvtColor

COLOR BGR2GRAY = 6 彩色到灰度

COLOR GRAY2BGR = 8 灰度到彩色

COLOR BGR2HSV = 40 BGR到HSV

COLOR HSV2BGR = 54 HSV到 BGR

imread 读取后的是BGR三通道+透明度的8位的图像

HSV H:0~180, S,V: 0~255 H和S表示颜色,V用来决定图像的亮度,S可以调整饱和度

4,Mat对象(包含header/data block)

ones用于三通道时只会把第一个值赋值为1

=号赋值,指针指向同一个对象

copyTo和clone才是新增一个对象

Mat mat = Scalar(255,255,255); 直接对通道赋值

5,图像像素的读写操作(双for循环)

1,数组下标方式

单通道-灰度图像值读取

int pv image.at(row.col);

image.at(row,col) = 255 - pv;

三通道-彩色图像值读取

Vec3b bgr = image.at(row, col);

image.at(row,col)[0] = 255 - bgr[0];

image.at(row,col)[1] = 255 - bgr[1];

image.at(row,col)[2] = 255 - bgr[2];

2,指针方式

单通道-灰度图像值读取

uchar* current_row = image.ptr(row);

int pv = *current_row;

*current_row++ = 255 - pv;

三通道-彩色图像值读取

*current_row++ = 255 - *current_row;

*current_row++ = 255 - *current_row;

*current_row++ = 255 - *current_row;

6,Mat算术操作

image + Scale(2,2,2); // add()

image - Scale(2,2,2); // subtract()

image / Scale(2,2,2); // divide()

Mat m = Mat::zeros(image.size(), image.type());

m = Scale(2,2,2);

multiply(image,m,dist);

saturate_cast(); // 限定在0-255, 小于或大于进行截断

6,滚动条演示操作(找到图像最佳参数)

static void on_lightness(int b, void* userdata) {

Mat image = *((Mat*)userdata);

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

Mat m = Mat::zeros(image.size(), image.type());

addWeighted(image, 1.0, m, 0, b, dst);

}

static void on_lightness(int b, void* userdata) {

Mat image = *((Mat*)userdata);

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

Mat m = Mat::zeros(image.size(), image.type());

addWeighted(image, b/100.0, m, 0.0, 0, dst); // 将两个图像加权相加

}

createTrackbar(“Value Bar: ”, “亮度调整”, 50, 100, on_lightness, (void*)(&image));

createTrackbar(“Contrast Bar: ”, “对比度调整”, 100, 200, on_contrast, (void*)(&image));

7,颜色风格转换(applyColorMap)

int colormap[]= {

COLORMAP_AUTUMN,

COLORMAP_BONE,

COLORMAP_JET,

COLORMAP_WINTER,

COLORMAP_RAINBOW,

COLORMAP_OCEAN,

COLORMAP_SUMMER,

COLORMAP_SPRING,

COLORMAP_COOL,

COLORMAP_PINK,

COLORMAP_HOT,

COLORMAP_PARULA,

COLORMAP_MAGMA,

COLORMAP_INFERNO,

COLORMAP_PLASMA,

COLORMAP_VIRIDIS,

COLORMAP_CIVIDIS,

COLORMAP_TWILIGHT,

COLORMAP_TWILIGHT_SHIFTED

};

Mat dst;

int index = 0;

while(true) {

int c = waitKey(2000);

if(c == 27) {

break;

}

applyColorMap(image,dst,colormap[index%19]);

index++;

imshow(“颜色风格”, dst);

}

8,图像像素的逻辑操作

void QuickDemo::bitwise_demo(Mat &image) {

Mat m1 = Mat::zeros(Size(256,256), CV_8UC3);

Mat m2 = Mat::zeros(Size(256,256), CV_8UC3);

rectangle(m1, Rect(100,100,80,80), Scalar(255,255,0), -1, LINE_8, 0);

rectangle(m1, Rect(150,150,80,80), Scalar(0,255,255), -1, LINE_8, 0);

imshow(‘m1’, m1);

imshow(‘m2’, m2);

Mat dst = ~image;

bitwise_xor(m1, m2, dst);

imshow(“像素位操作”, dst);

}

9,通道分离与合并

split / merge / mixChannels

void QuickDemo::channels_demo(Mat &image) {

std::vector mv;

split(image, mv);

imshow(“蓝色”, mv[0]);

imshow(“绿色”, mv[1]);

imshow(“红色”, mv[2]);

Mat dst;

mv[0] = 0;

// mv[2] = 0;

merge(mv, dst);

imshow(“绿色”, dst);

int from_to [] = {0,2, 1,1, 2,0};

mixChannels(&image, 1, &dst, 1, from_to, 3);

imshow(“通道混合”, dst);

}

10,提取指定色彩范围区域inRange

void QuickDemo::inrange_demo(Mat &image) {

Mat hsv;

cvtColor(image, hsv, COLOR_BGR2HSV);

Mat mask;

// hsv对应rgb的色彩空间值

inRange(hsv, Scalar(35, 43, 46), Scalar(77,255,255), mask);

Mat redback = Mat::zeros(image.size(), image.type());

redback = Scalar(40,40,200);

bitwise_not(mask, mask);

imshow(‘mask’, mask);

image.copyTo(redback, mask)

imshow(“roi区域提取”, redback);

}

11, 像素统计信息

最大最小值minMaxLoc

double minv,maxv;

Point minLoc,maxLoc;

std::vector mv;

split(image, mv);

for(int i = 0; i

minMaxLoc(mv[i], &minv, &minLoc, &maxLoc, Mat());

}

计算均值与标准方差meanStdDev

Mat mean,stddev;

meanStdDev(image, mean, stddev);

mean.at(0,0);

std::cout << “means: ” << mean << std::endl;

std::cout << “stddev: ” << stddev<< std::endl;

12,图像几何形状绘制

Rect rect;

rect.x = 100;

rect.y = 100;

rect.width = 250;

rect.height = 300;

rectangle(bg, rect, Scalar(0,0,255), -1, 8, 0);

circle(bg, Point(350,400), 15, Scalar(255,0,0), -1, 8, 0);

line(bg, Point(100,100), Point(350, 400), Scalar(0,255,0), 4, LINE_AA, 0);

RotatedReat rrt; // 椭圆

rrt.center = Point(200,200);

rrt.size = Size(100, 200);

rrt.angle = 90.0;

ellipse(bg, rrt, Scalar(0,255,255),2,8); // 绘制椭圆

Mat dst;

addWeighted(image, 0.7, bg, 0.3, 0, dst);

imshow(“绘制演示”, bg);

13,随机数与随机颜色

void QuickDemo::random_drawing(){

Mat canvas = Mat::zeros(Size(512,512), CV_8UC3);

int w = canvas.cols;

int h = canvas.rows;

RNG rng(12345);

while(true) {

int c = waitKey(10);

if(c == 27) {

break;

}

int x1 = rng.uniform(0, w);

int y1 = rng.uniform(0, h);

int b = rng.uniform(0, 255);

int g = rng.uniform(0, 255);

int r = rng.uniform(0, 255);

// canvas = Scalar(0,0,0); //清空

line(canvas, Point(x1, y1), Point(x1, y1), Scalar(b,g,r),1,LINE_AA, 0);

imshow(“随机绘制演示”, canvas);

}

}

14,绘制多边形

void QuickDemo::polyline_drawing_demo() {

Mat canvas = Mat::zeros(Size(512,512), CV_8UC3);

Point p1(100, 100);

Point p2(350, 100);

Point p3(450, 280);

Point p4(320, 450);

Point p5(80, 400);

std::vector pts;

pts.push_back(p1);

pts.push_back(p2);

pts.push_back(p3);

pts.push_back(p4);

pts.push_back(p5);

// fillPoly(canvas, pts, Scalar(255,0,255), 8, 0);

// polylines(canvas, pts, true, Scalar(0,0,255), 2, LINE_AA, 0);

std::vector> contours;

contours.push_back(pts);

drawContours(canvas, contours, -1, Scalar(255, 0, 0), -1);

imshow(“多边形绘制”, canvas);

}

15,鼠标响应操作

注册和监控鼠标事件

void cv::setMousecallback(const String, &winname, MouseCallback onMouse, void * userdata = 0);

typedef void(* cv::MouseCallback)(int event, int x, int y, int flags, void * userdata);

Point sp(-1, -1);

Point ep(-1, -1);

Mat temp;

static void on_draw(int event, int x, int y, int flags, void * userdata) {

Mat image = *((Mat) userdata);

if(event == EVENT_LBUTTONDOWN) {

sp.x = x;

sp.y = y;

std::cout << “start point: ” << sp << std::endl;

}else if(event == EVENT_LBUTTONUP) {

ep.x = x;

ep.y = y;

int dx = ep.x - sp.x;

int dy = ep.y - sp.y;

if (dx > 0 && dy > 0) {

Rect box(sp.x, sp.y, dx, dy);

temp.copyTo(image);

imshow(“ROi区域”, image(box));

rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);

imshow(“鼠标绘制”, image);

sp.x = -1;

sp.y = -1;

}

}else if (event == EVENT_MOUSEMOVE) {

if (sp.x > 0 && sp.y > 0) {

ep.x = x;

ep.y = y;

int dx = ep.x - sp.x;

int dy = ep.y - sp.y;

if (dx > 0 && dy > 0) {

Rect box(sp.x, sp.y, dx, dy);

temp.copyTo(image);

rectangle(image, box, Scalar(0, 0, 255), 2, 8, 0);

imshow(“鼠标绘制”, image);

}

}

}

}

void QuickDemo::mouse_drewing_demo(Mat &image){

namedWindow(“鼠标绘制”, WINDOW_AUTOSIZE);

setMouseCallback(“鼠标绘制”, on_draw, (void *) &image);

imshow(“鼠标绘制”, image);

temp = image.clone();

}

16, 图像像素类型转换与归一化

void QuickDemo::norm_demo(Mat &image) {

Mat dst;

std::cout << image.type() << std::endl;

image.convertTo(image, CV_32F); // 整型转浮点型

std::cout << image.type() << std::endl;

normalize(image, dst, 1.0, 0, NORM_MINMAX);

std::cout << dst.type() << std::endl;

imshow(“图像数据归一化”, dst);

}

17, 图像放缩与插值(邻近插值和线性插值较快,卢卡斯和双立方插值较慢)

void QuickDemo::resize_demo(Mat &image) {

Mat zoomin, zoomout;

int h = image.rows;

int w = image.cols;

resize(image, zoomin,Size(w/2, h/2), 0,0, INTER_LINER);

imshow(“zoomin”, zoomin);

resize(image, zoomout,Size(w*1.5, h*1.5), 0,0, INTER_LINER);

imshow(“zoomout”, zoomout);

}

18,图像翻转

void QuickDemo::flip_demo(Mat &image) {

Mat dst;

// flip(image, dst, 0); // 上下翻转

// flip(image, dst, 1); // 左右翻转

flip(image, dst, -1); // 180度旋转

imshow(“图像翻转”, dst);

}

19,图像平移旋转

void QuickDemo::rotate_demo(Mat &image) {

Mat dst, M;

int w = image.cols;

int h = image.rows;

M = getRotationMatrix2D(Point2f(w/2, h/2), 45, 1.0); // 中心点,旋转角度,放缩大小

double cos = abs(M.at(0,0));

double sin = abs(M.at(0,1));

int nw = cos*w + sin*h;

int nh = sin*w + cos*h;

M.at(0,2) += (nw/2 - w/2);

M.at(1,2) += (nh/2 - h/2);

warpAffine(image, dst, M, Size(nw,nh), INNER_LINEAR, 0, Scalar(255,255,0));

imshow(“旋转演示”, dst);

}

20,视频摄像头使用

void QuickDemo::video_demo(Mat &image) {

VideoCapture capture(“D:/images/video/01.mp4”); // 为0就是获取电脑摄像头

Mat frame;

while(true) {

capture.read(frame);

flip(frme, frme, 1);

if(frame.empty()) {

break;

}

imshow(“frame”, frame);

int c = waitKey(50);

if (c == 27) {

break;

}

}

capture.release();

}

21, 视频处理与保存(set 方法要看设备是否支持)

一般的手机分辨率320p或者480p

SD 标清

HD 高清 720p - 1080p

UHD 超清

fps 一秒钟处理多少帧

void QuickDemo::video_demo(Mat &image) {

VideoCapture capture(“D:/images/video/01.mp4”); // 为0就是获取电脑摄像头

int frame_width = capture.get(CAP_PROP_FRAME_WIDTH);

int frame_height = capture.get(CAP_PROP_FRAME_HEIGHT);

int count = capture.get(CAP_PROP_FRAME_COUNT);

int fps = capture.get(CAP_PROP_FPS);

std::cout << “frame width: ” << frame_width << std::endl;

std::cout << “frame height: ” << frame_height << std::endl;

std::cout << “fps: ” << fps << std::endl;

std::cout << “number of frames: ” << count << std::endl;

VideoWriter writer(“D:/test.mp4”, capture.get(CAP_PROP_FOURCC), fps, Size(frame_width, frame_height), true);

Mat frame;

while(true) {

capture.read(frame);

flip(frme, frme, 1);

if(frame.empty()) {

break;

}

imshow(“frame”, frame);

writer.write(frame);

int c = waitKey(50);

if (c == 27) {

break;

}

}

capture.release();

writer.release();

}

22,图像直方图

calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);

cv.calcHist([image], [i], None, [256], [256]);

void showHistogram(Mat &image) {

// 三通道分离

vector bgr_plane;

split(src, bgr_plane);

// 定义参数变量

const int channels[1] = {0};

const int bins[1] = {256};

float hranges[2] = {0, 255};

const float* ranges[1] = {hranges};

Mat b_hist;

Mat g_hist;

Mat r_hist;

// 计算blue,green,red通道的直方图

calcHist(&bgr_plane[0], 1, 0, Mat(), b_hist, 1, bins, ranges);

calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, bins, ranges);

calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, bins, ranges);

// 显示直方图

int hist_w = 512;

int hist_h = 400;

int bin_w = cvRound((double) hist_w / bins[0]);

Mat histImage = Mat::zeros(hist_h, hist_w,CV_8UC3);

// 归一化直方图数据

normalize(b_hist, b_hist,0,histImage.rows,NORM_MINMAX,-1,Mat());

normalize(g_hist, g_hist,0,histImage.rows,NORM_MINMAX,-1,Mat());

normalize(r_hist, r_hist,0,histImage.rows,NORM_MINMAX,-1,Mat());

// 绘制直方图曲线

for(int i = 1; i

line(histImage, Point(bin_w*(i-1), hist_h - cvRound(b_hist.at(i-1))), Point(bin_w*(i-1), hist_h - cvRound(b_hist.at(i))), Scalar(255,0,0,0),2,8,0);

line(histImage, Point(bin_w*(i-1), hist_h - cvRound(g_hist.at(i-1))), Point(bin_w*(i-1), hist_h - cvRound(g_hist.at(i))), Scalar(255,0,0,0),2,8,0);

line(histImage, Point(bin_w*(i-1), hist_h - cvRound(r_hist.at(i-1))), Point(bin_w*(i-1), hist_h - cvRound(r_hist.at(i))), Scalar(255,0,0,0),2,8,0);

}

// 显示直方图

namedWindow(“Histogram Demo”, WINDOW_AUTOSIZE);

imshow(“Histogram Demo”, histImage);

}

23,二维直方图

void QuickDemo::histogram_2d_demo(Mat &image) {

Mat hsv, hs_hist;

cvtColor(image, hsv, COLOR_BGR2HSV);

int hbins = 30, sbins = 32;

int hist_bins[] = {hbins, sbins};

float h_range[] = {0, 180};

float s_range[] = {0,256};

const float* hs_ranges[] = {h_range, s_range};

int hs_channels[] = {0, 1};

calcHist(&hsv, 1, hs_channels, Mat(), hs_hist, 2, hist_bins, hs_ranges, true, false);

double maxVal = 0;

minMaxLoc(hs_hist, 0, &maxVal, 0, 0);

int scale = 10;

Mat hist2d_image = Mat::zeros(sbin* scale, hbins* scale, CV_8UC3);

for(int h = 0; h < hbins; h++) {

for(int s = 0; s

float binVal = hs_hist.at(h,s);

int intensity = cvRound(binVal * 255 / maxVal);

ractangle(hist2d_image,

Point(h*scale,s*scale),

Point((h+1)*scale-1, (s-1)*scale - 1),

Scalar::all(intensity),-1);

}

}

}

24,直方图均衡化(只支持单通道,用于图像增强)

void QuickDemo::histogram_eq_demo(Mat &image) {

Mat gray;

cvtColor(image, gray, COLOR_BGR2GRAY);

imshow(“灰度图像”, gray);

Mat dst;

equalizeHist(gray, dst);

imshow(“直方图均衡化演示”, dst);

}

25,图像卷积操作

void QuickDemo::blur_demo(Mat &image){

Mat dst;

blur(image, dst, Size(3,3), Point(-1, -1));

imshow(“图像模糊”, dst);

}

26,高斯模糊

void QuickDemo::blur_demo(Mat &image){

Mat dst;

GaussianBlur(image, dst, Size(0,0), 15); // size不能为偶数,为0自动计算西格玛

imshow(“图像模糊”, dst);

}

27,高斯双边模糊(滤波)

void QuickDemo::blur_demo(Mat &image){

Mat dst;

bilateralFilter(image, dst, 0, 100, 10);

imshow(“双边模糊”, dst);

}

28,人脸检测

cv::dnn::Net cvnet = dnn::readNetFromTensorflow(“opencv_face_detector_uint8.pb”, “opencv_face_detector.pbtxt”);

    map, string> fdlib;

    for (auto & file : files) {

        cv::Mat frame = cv::imread(file.first);

//        cv::pyrDown(frame, frame, frame.size() / 2);

        Mat inputBlob = cv::dnn::blobFromImage(frame, 1.0, Size(300, 300), Scalar(104.0, 177.0, 123.0), false, false);

        cvnet.setInput(inputBlob);

        Mat detection = cvnet.forward();

        Mat detectionMat(detection.size[2], detection.size[3], CV_32F, detection.ptr());

        std::vector> faces;

        for (int i = 0; i < detectionMat.rows; i++)

        {

            float confidence = detectionMat.at(i, 2);

            if (confidence > 0.5)

            {

                cout << "confidence" << confidence << endl;

                int x1 = static_cast(detectionMat.at(i, 3) * frame.cols);

                int y1 = static_cast(detectionMat.at(i, 4) * frame.rows);

                int x2 = static_cast(detectionMat.at(i, 5) * frame.cols);

                int y2 = static_cast(detectionMat.at(i, 6) * frame.rows);

                // 在图像上画出检测框

//                rectangle(frame, Point(x1, y1), Point(x2, y2), Scalar(0, 255, 0), 2);

//                cv::imwrite("/home/xingyue/CLionProjects/dlibTest/tttt/" + file.second, frame);

                cv::Rect roi(x1, y1, x2 - x1, y2 - y1);

                cv::Mat roi_image = frame(roi);

                cv::imshow("roi_image", roi_image);

        }

你可能感兴趣的:(opencv,人工智能,计算机视觉)