目录
12、opencv获取图像最大值像素点、最小值像素点、均值和方差
15、opencv好玩的代码:学了这么多觉得有点枯燥,做点新玩意
17、openCV卷积操作 (根据原理写代码,openCV的卷积API为blur)
1、opencv简单的读取和显示图片
如果不设置imread的读入参数,默认读入的为彩色图片
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv){
Mat src = imread("F:/images/zwj.jpg"); //读取图片
if (src.empty()) { //判断是否找到图片
printf("没有找到图片 "); //输出文字
return -1;
}
else
{
namedWindow("input",WINDOW_AUTOSIZE);// 显示窗口命名为input ;WINDOW_AUTOSIZE显示大小为图片自定义大小,且不可以更改大小
imshow("input",src); //显示
waitKey(0);//显示的毫秒时间,如果函数参数<=0表示一直显示。>0表示显示的时间
destroyAllWindows();
return 0;
}
}
2、opencv加载一个灰度图像
只要设置imread的参数:IMREAD_GRAYSCALE(PS:彩色图像的参数为:IMREAD_ANYCOLOR)
3、 Mat创建方法
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv){
Mat src = imread("D:/Program Files/opencv/sources/samples/data/opencv-logo.png",IMREAD_GRAYSCALE);
if(src.empty()){
printf("没有此图片,请检查路径是否正确");
return -1;
}
else
{
namedWindow("图片",WINDOW_AUTOSIZE);
imshow("图片",src);
int width = src.cols;//宽带
int higth = src.rows;//高度
int dim = src.channels();//查看维度
int d = src.depth();//
int t = src.type();//图像类型
if(t==CV_8UC3){
printf("width: %d|,higth : %d dim %d", width, higth, dim);
printf("深度:%d,类型:%d", d, d);
}
//怎么创建Mat
//创建方法一
Mat t1 = Mat(256,256,CV_8UC3);
t1 = Scalar(0,0,255);
imshow("t1",t1);
//创建方法二
Mat t2 = Mat(512, 512, CV_8UC3);
t2 = Scalar(255,0,255);
imshow("t2",t2);
//创建方法三
Mat t3 = Mat::zeros(Size(256,256),CV_8UC3);
//3 = Scalar(255,0,0);
imshow("t3",t3);
//创建方法四:复制克隆方法
Mat t4 = src.clone();
imshow("t4",t4);
//创建方法五
Mat t5 = Mat::zeros(src.size(), src.type());//创建一个和原图大小一样,类型一样的图
imshow("t5", t5);
waitKey(0);
destroyAllWindows();
return 0;
}
}
4、opencv如何遍历所有像素点
普通方法:基于数组遍历
//如何遍历访问所有Mat的像素值
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv){
Mat src = imread("D:/Program Files/opencv/sources/samples/data/opencv-logo.png",IMREAD_GRAYSCALE);
if (src.empty()) {
printf("没找到图片,请检查路径");
return -1;
}
else
{
namedWindow("图像",WINDOW_FREERATIO);
imshow("图像",src);
//遍历访问像素值
//首先知道图像的长高
int width = src.cols;
int higth = src.rows;
int dim = src.channels();
for (int row = 0; row < higth;row++) {
for (int col = 0; col < width;col++) {
if (dim==3) {
Vec3b pixel=src.at<Vec3b>(row, col);//字节类型3通道的Vec3b,int 类型Vec3i获得
int blue = pixel[0];
int green = pixel[1];
int red = pixel[2];
src.at<Vec3b>(row, col)[0] = 255 - blue;
src.at<Vec3b>(row, col)[1] = 255 - green;
src.at<Vec3b>(row, col)[2] = 255 - red;
}
else if(dim==1){
int pv = src.at<uchar>(row, col);//单通道的灰度是char类型
src.at<uchar>(row, col) = (255 - pv);
}
}
}
imshow("像素测试图像", src);
waitKey(0);
destroyAllWindows();
return 0;
}
}
高级遍历方式:基于指针遍历方式
//如何遍历访问所有Mat的像素值
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv){
Mat src = imread("D:/Program Files/opencv/sources/samples/data/opencv-logo.png",IMREAD_ANYCOLOR);
if (src.empty()) {
printf("没找到图片,请检查路径");
return -1;
}
else
{
namedWindow("图像",WINDOW_FREERATIO);
imshow("图像",src);
//遍历访问像素值
//首先知道图像的长高
int width = src.cols;
int higth = src.rows;
int dim = src.channels();
//基于指针的遍历方式
Mat result = Mat::zeros(src.size(),src.type());
// 基于数组遍历方式
for (int row = 0; row < higth;row++) {
uchar*curr_row = src.ptr<uchar>(row);//获取当前行的指针
uchar*result_row = result.ptr<uchar>(row);
for (int col = 0; col < width;col++) {
if (dim==3) {
int blue = *curr_row++;
int green = *curr_row++;
int red = *curr_row++;
*result_row++ = blue;
*result_row++ = green;
*result_row++ = red;
}
else if(dim==1){
int pv = *curr_row++;
*result_row++ = pv;
}
}
}
imshow("像素测试图像", result);
waitKey(0);
destroyAllWindows();
return 0;
}
}
5、opencv进行图像腐蚀和膨胀
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
Mat src = imread("D:/images/smarties.png"); //读取图片
if (src.empty()) { //判断是否找到图片
printf("没有找到图片 "); //输出文字
}
else
{
namedWindow("原图", WINDOW_AUTOSIZE);// 显示窗口命名为input ;WINDOW_AUTOSIZE显示大小为图片自定义大小,且不可以更改大小
imshow("原图", src); //显示
Mat str1= getStructuringElement(MORPH_RECT,Size(50, 50));
Mat fsImg;
erode(src,fsImg,str1);
imshow("腐蚀图像",fsImg);
Mat str2 = getStructuringElement(MORPH_RECT, Size(20, 20));
Mat pzImg;
dilate(src, pzImg, str2);
imshow("膨胀图像", pzImg);
waitKey(0);//显示的毫秒时间,如果函数参数<=0表示一直显示。>0表示显示的时间
destroyAllWindows();
return 0;
}
}
6、opencv均值滤波
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv) {
Mat src = imread("F:/images/zwj.jpg");
if (src.empty()) {
printf("没有找到图像,请检查路径是否正确");
return -1;
}
else
{
//显示原图
namedWindow("原图像",WINDOW_FREERATIO);
imshow("原图像",src);
//均值滤波
Mat dstImg;
blur(src,dstImg,Size(20,20));
imshow("滤波后的图像",dstImg);
waitKey(0);
destroyAllWindows();
return 0;
}
}
7、opencv边缘检测
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv) {
Mat src = imread("F:/images/zwj.jpg");
if (src.empty()) {
printf("未发现图像,请检查图片路径");
return -1;
}
else {
imshow("原图像",src);
//边缘检测
Mat dstImg, edge, grayImg;
dstImg.create(src.size(), src.type());//创建一个和src同类型大小的图像
cvtColor(src, grayImg, COLOR_BGR2GRAY);
//降噪
blur(grayImg,edge,Size(3,3));
//边缘检测
Canny(edge, edge, 3, 9, 3);
//显示
imshow("边缘检测图",edge);
waitKey(0);
destroyAllWindows();
return 0;
}
}
8、opencv读取视频
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv) {
VideoCapture capture("D:/Program Files/opencv/sources/samples/data/vtest.avi");
while (true)
{
Mat frame;//定义一个Mat变量存储每一个帧图像
capture >> frame;
imshow("读取视频",frame);//显示当前帧数
waitKey(30);//延时30ms
}
return 0;
}
9、opencv对视频进行Canny边缘检测处理
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
VideoCapture capture("D:/Img/蔡徐坤.mp4");
Mat edge;
while (true)
{
// 读取原图像
Mat frame;//定义一个Mat变量存储每一个帧图像
capture >> frame;//读取当前帧图片
//将原图像转换为灰度
cvtColor(frame,edge,COLOR_BGR2GRAY);//转换为灰度图像
//滤波降噪处理
blur(edge,edge,Size(7,7));
//边缘检测Canny算子
Canny(edge,edge,0,30,3);
imshow("Canny边缘检测算子处理后的图像",edge);
waitKey(1);//延时1ms
}
destroyAllWindows();
return 0;
}
10、opencv对图像进行加减乘除操作
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc, int argv) {
Mat src1 = imread("D:/Program Files/opencv/sources/samples/data/LinuxLogo.jpg");
Mat src2= imread("D:/Program Files/opencv/sources/samples/data/WindowsLogo.jpg");
if (src1.empty()&&src2.empty()) {
printf("没有找到图像,请检查路径是否正确");
return -1;
}
else
{
imshow("demo1", src1);
imshow("demo2", src2);
//代码演示
Mat dst1;
add(src1, src2,dst1);
imshow("加法",dst1);
//减法操作
Mat dst2;
subtract(src1, src2, dst2);
imshow("减法", dst2);
//乘法操作
Mat dst3;
multiply(src1, src2, dst3);
imshow("乘法", dst3);
//除法操作
Mat dst4;
divide(src1, src2, dst4);
imshow("除法操作", dst4);
waitKey(0);
destroyAllWindows();
return 0;
}
}
11、opencv调用摄像头
#include <opencv2/core.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
int main(int, char**)
{
Mat frame;
VideoCapture cap;
int deviceID = 0;
int apiID = 0;
cap.open(deviceID, apiID);
while (true)
{
cap.read(frame);
if (frame.empty()) {
cerr << "错误,空白帧\n";
break;
}
imshow("调用摄像头", frame);
waitKey(4);
}
return 0;
}
12、opencv获取图像最大值像素点、最小值像素点、均值和方差
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc,char** argv) {
Mat src = imread("F:/images/zwj.jpg",IMREAD_GRAYSCALE);
if (src.empty()) {
printf("没有图片");
return -1;
}
else {
namedWindow("input", WINDOW_AUTOSIZE);
imshow("input", src);
int w = src.cols;//宽
int h = src.rows;//高
int dim = src.channels();//维度
printf("w:%d,h:%d,dim:%d\n",w,h,dim);//
double min_val;
double max_val;
Point maxloc;
Point minloc;
minMaxLoc(src,&min_val,&max_val,&minloc,&maxloc);//获取图像像素点的最大值和最小值,以及索引位置
printf("min:%.2f,max:%.2f\n",min_val,max_val);//打印最大最小像素点
printf("minX:%d,minY:%d maxX:%d,maxY:%d\n",minloc.x, minloc.y, maxloc.x, maxloc.y);//打印最大最小像素点的位置
//均值
Scalar s = mean(src);
printf("均值:%.2f\n",s[0]);//因为灰度是单通道的s[0],PS:彩色图像是三通道的s[0],s[1],s[2]
//方差
Mat mm,mstd;
meanStdDev(src,mm,mstd);//均值和方差
int rows = mstd.rows;
int cols = mstd.cols;
printf("rows:%d,cols:%d\n",rows,cols);
printf("均值:%.3f,方差:%.3f\n",mm.at<double>(0,0),mstd.at<double>(0,0));
waitKey(0);
destroyAllWindows();
return 0;
}
}
13、opencv画线、矩形、椭圆、圆形
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat canvas = Mat::zeros(Size(512,512),CV_8UC3);
namedWindow("画布图像", WINDOW_AUTOSIZE);
imshow("画布图像", canvas);
//相关绘制
//线
line(canvas,Point(10,10),Point(400,400),Scalar(0,0,255),2,LINE_8);//画布、起、始点、颜色、线宽、渲染方式
//矩形
Rect rect(100,100,200,200);//绘制矩形
rectangle(canvas,rect,Scalar(255,0,0),3,8);
circle(canvas, Point(256, 256), 100, Scalar(0,255, 0),-3, 8);//画布、圆心、半径、颜色、线宽、渲染方式
//椭圆
RotatedRect rrt;
rrt.center = Point2f(256,256);
rrt.angle =CV_PI/4;// pi/4
rrt.size=Size(100,200);
ellipse(canvas, rrt, Scalar(0, 255, 255), -1, 8);
//注:线宽<0则是填充图案
imshow("画线段",canvas);
waitKey(0);
destroyAllWindows();
return 0;
}
14、opencv分离图像通道
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat src = imread("F:/images/zwj.jpg");
if (src.empty()) {
printf("没有图片");
return -1;
}
else {
namedWindow("原图", WINDOW_AUTOSIZE);
vector<Mat> mv;
split(src,mv);//分离通道
int size = mv.size();
printf("通道数目:%d\n",size);//打印通道数目
imshow("blue",mv[0]);//第一通道
imshow("green:", mv[1]);//第二通道
imshow("red", mv[2]);//第三通道
mv[1] = Scalar(0);
Mat dst;
merge(mv,dst);//合并
imshow("result",dst);
imshow("原图", src);
waitKey(0);
destroyAllWindows();
return 0;
}
}
15、opencv好玩的代码:学了这么多觉得有点枯燥,做点新玩意
注意:因为opencv不支持中文,解决方案见:这位大佬的,把源码拷贝过来就行了
#include<opencv2/opencv.hpp>
#include "putText.h"
#include<iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
Mat image = Mat::zeros(Size(1000, 800), CV_8UC3);
int row = image.rows;
int col = image.cols;
//提前声明坐标变量
int x1 = 0, y1 = 0;
RNG rng;
while (true)
{
x1 = (int)rng.uniform(0, col-1);
y1 = (int)rng.uniform(0, row-1);
//image = Scalar(0,0,0);
putTextZH(image,"帅", Point(x1, y1),Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), rng.uniform(0,200),"宋体");
imshow("别人都夸我帅", image);
char c = waitKey(100);
if (c == 27) {
break;
}
}
waitKey(0);
destroyAllWindows();
return 0;
}
16、opencv绘制直方图
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc,char** argv) {
Mat src = imread("F:/images/zwj.jpg");
if (src.empty()) {
cout << "没有图片请 检查路径" << endl;
return -1;
}
else
{
namedWindow("原图像",WINDOW_AUTOSIZE);
imshow("原图像",src);
vector<Mat>mv;
split(src,mv);
//计算直方图
int histSize = 256;
Mat b_hist, g_hist, r_hist;
float range[] = {0,255};
const float* histRanges= { range};
calcHist(&mv[0],1,0,Mat(),b_hist,1,&histSize,&histRanges,true,false);
calcHist(&mv[1],1,0,Mat(),g_hist,1,&histSize,&histRanges,true, false);
calcHist(&mv[2],1,0,Mat(),r_hist,1,&histSize,&histRanges,true, false);
Mat result = Mat::zeros(Size(src.rows,src.cols),CV_8UC3);
int margin = 50;
int h = result.rows;
int nm = result.rows - 2 * margin;
normalize(b_hist ,b_hist, 0, nm, NORM_MINMAX, -1, Mat());
normalize(g_hist, g_hist, 0, nm, NORM_MINMAX, -1, Mat());
normalize(r_hist, r_hist, 0, nm, NORM_MINMAX, -1, Mat());
float step = 500 / 256;
for (int i = 0; i < 255; i++) {
line(result, Point(step*i, 50 + (nm - b_hist.at<float>(i, 0))), Point(step*(i + 1), 50 + (nm - b_hist.at<float>(i + 1, 0))), Scalar(255, 0, 0), 2, 8, 0);
line(result, Point(step*i, 50 + (nm - g_hist.at<float>(i, 0))), Point(step*(i + 1), 50 + (nm - g_hist.at<float>(i + 1, 0))), Scalar(0, 255, 0), 2, 8, 0);
line(result, Point(step*i, 50 + (nm - r_hist.at<float>(i, 0))), Point(step*(i + 1), 50 + (nm - r_hist.at<float>(i + 1, 0))), Scalar(0, 0, 255), 2, 8, 0);
}
imshow("demo",result);
waitKey(0);
return 0;
}
}
17、openCV卷积操作 (根据原理写代码,openCV的卷积API为blur)
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argv,char** argc) {
Mat src = imread("F:/images/zwj.jpg");
if(src.empty()){
cout << "没有找到图片,请检查路径是否正确" << endl;
return -1;
}
namedWindow("原图",WINDOW_AUTOSIZE);
imshow("原图",src);
int w = src.cols;
int h = src.rows;
Mat result = src.clone();
for ( int row = 1; row < w-1; row++)
{
for (int col = 1; col < h-1; col++)
{
//3*3的卷积核
int sb = src.at<Vec3b>(row, col)[0] + src.at<Vec3b>(row - 1, col - 1)[0] + src.at<Vec3b>(row - 1, col)[0] +
src.at<Vec3b>(row - 1, col + 1)[0] +src.at<Vec3b>(row, col-1)[0]+ src.at<Vec3b>(row, col+1)[0]+
src.at<Vec3b>(row+1, col-1)[0]+ src.at<Vec3b>(row+1, col)[0]+ src.at<Vec3b>(row+1, col+1)[0];
int sg = src.at<Vec3b>(row, col)[1] + src.at<Vec3b>(row - 1, col - 1)[1] + src.at<Vec3b>(row - 1, col)[1] +
src.at<Vec3b>(row - 1, col + 1)[1] + src.at<Vec3b>(row, col - 1)[1] + src.at<Vec3b>(row, col + 1)[1] +
src.at<Vec3b>(row + 1, col - 1)[1] + src.at<Vec3b>(row + 1, col)[1] + src.at<Vec3b>(row + 1, col + 1)[1];
int sr = src.at<Vec3b>(row, col)[2] + src.at<Vec3b>(row - 1, col - 1)[2] + src.at<Vec3b>(row - 1, col)[2] +
src.at<Vec3b>(row - 1, col + 1)[2] + src.at<Vec3b>(row, col - 1)[2] + src.at<Vec3b>(row, col + 1)[2] +
src.at<Vec3b>(row + 1, col - 1)[2] + src.at<Vec3b>(row + 1, col)[2] + src.at<Vec3b>(row + 1, col + 1)[2];
result.at<Vec3b>(row, col)[0] = sb/9 ;
result.at<Vec3b>(row, col)[1] = sg/9;
result.at<Vec3b>(row, col)[2] = sr/9;
}
}
imshow("卷积",result);
waitKey(0);
destroyAllWindows();
return 0;
}