学习Opencv不得不掌握的操作

共 7066字,需浏览 15分钟

 ·

2021-09-07 00:28

点击下方卡片,关注“新机器视觉”公众号

视觉/图像重磅干货,第一时间送达

转自 | 小白学视觉

小白导读

学习计算机视觉最重要的能力应该就是编程了,为了帮助小伙伴尽快入门计算机视觉,小白准备了【走进OpenCV】系列,主要帮助小伙伴了解如何调用OpenCV库,涉及到的知识点会做简单讲解。

图像初始化操作


#include<opencv2\opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
      //这些方式都是自己拥有独立的内存空间
   Mat img1(22, CV_8UC3, Scalar(00255));
   cout << img1 << endl;
   int sz[3] = { 2,2,2 };
   Mat img2(3, sz, CV_8UC1, Scalar(000));
   //cout << img2 << endl;
   Mat img5;
   img5.create(44, CV_8UC3);
   cout << img5 << endl;
   Mat img6 = Mat::zeros(44, CV_8UC3);
   cout << img6 << endl;
   Mat img7 = img6.clone();
   cout << img7 << endl;
   Mat img8;
   img6.copyTo(img8);
   cout << img8 << endl;
   //下面都是浅拷贝,指针指向同一个实例
   Mat img9 = img8;
   Mat img10(img8);
   waitKey(0);
   return 0;
}


图像二值化操作


两种方法,全局固定阈值二值化和局部自适应阈值二值化全局固定阈值很容易理解,就是对整幅图像都是用一个统一的阈值来进行二值化;局部自适应阈值则是根据像素的邻域块的像素值分布来确定该像素位置上的二值化阈值。

#include<opencv2\opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
   Mat image = imread("lol1.jpg", CV_LOAD_IMAGE_GRAYSCALE); //注意了,必须是载入灰度图
   if (image.empty())
   {
       cout << "read image failure" << endl;
       return -1;
   }
   // 全局二值化
   int th = 100;
   Mat global;
   threshold(image, global, th, 255, CV_THRESH_BINARY_INV);
   // 局部二值化
   int blockSize = 25;
   int constValue = 10;
   Mat local;
   adaptiveThreshold(image, local, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, blockSize, constValue);
   imshow("全局二值化", global);
   imshow("局部二值化", local);
   waitKey(0);
   return 0;
}


原始图

两种二值化效果对比

腐蚀操作


#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
   Mat SrcPic = imread("lena.jpg");
   imshow("Src Pic", SrcPic);
   Mat element = getStructuringElement(MORPH_RECT, Size(1515)); //getStructuringElement函数返回的是指定形状和尺寸的结构元素
   Mat DstPic;
   erode(SrcPic, DstPic, element); //腐蚀操作
   imshow("腐蚀效果图", DstPic);
   waitKey();
   return 0;
}

运行效果

均值滤波实现图像模糊


#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
   Mat SrcPic = imread("lena.jpg");
   imshow("Src Pic", SrcPic);
   Mat DstPic;
   blur(SrcPic, DstPic, Size(77));
   imshow("均值模糊效果图", DstPic);
   waitKey();
   return 0;
}

运行效果

canny边缘检测


思路:将原始图像转化为灰度图,用blur函数进行图像模糊以降噪,然后用canny函数进行边缘检测。

#include <iostream>
#include <opencv2\opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
   Mat SrcPic = imread("lena.jpg");
   imshow("Src Pic", SrcPic);
   Mat DstPic, edge, grayImage;
   //创建与src同类型和同大小的矩阵
   DstPic.create(SrcPic.size(), SrcPic.type());
   //将原始图转化为灰度图
   cvtColor(SrcPic, grayImage, COLOR_BGR2GRAY);
   //先使用3*3内核来降噪
   blur(grayImage, edge, Size(33));
   //运行canny算子
   Canny(edge, edge, 393);
   imshow("边缘提取效果", edge);
   waitKey();
   return 0;
}

运行效果

转为灰度图


#include<opencv2\opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
int main()
{
   Mat img = imread("lol1.jpg");
   Mat dstImg;
   cvtColor(img, dstImg,COLOR_BGR2GRAY);//从宏名字就可以知道,是彩色图转换到灰度图
   imshow("灰度图", dstImg);
   waitKey(0);
}

灰度图

访问图片中像素


#include<opencv2\opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
//访问每个像素,我喜欢使用指针的方式
int main()
{
   Mat img = imread("lol1.jpg");
   for (int i = 0; i < img.rows; i++)
   {
       uchar* data = img.ptr<uchar>(i);  //获取第i行地址
       for (int j = 0; j < img.cols; j++)
       {
            printf("%d\n",data[j]);
       }
   }
   waitKey(0);
}


直方图均衡化


#include<opencv2\opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>
using namespace std;
using namespace cv;
//直方图均衡化
int main()
{
   Mat img = imread("lol3.jpg");
   imshow("原始图", img);
   Mat dst;
   cvtColor(img, img, CV_RGB2GRAY);
   imshow("灰度图", img);
   equalizeHist(img, dst);
   imshow("直方图均衡化", dst);
   waitKey(0);
}

显然均衡化后的图片对比度变高了,变得更加明亮!

常用的数据结构


#include<opencv2\opencv.hpp>  
#include<opencv2\highgui\highgui.hpp>

using namespace std;
using namespace cv;

//常见数据结构使用方法总结
int main()
{
   //Mat的用法
   Mat m1(22, CV_8UC3, Scalar(00255))//其中的宏的解释:CV_[位数][带符号与否][类型前缀]C[通道数]
   cout << m1 << endl;

   //或者,利用IplImage指针来初始化,将IplImage*转化为Mat
   IplImage* image = cvLoadImage("lena.jpg");
   Mat mat = cvarrToMat(image);

   //Mat转IplImage:
   IplImage img = IplImage(mat);

   //或者
   Mat m2;
   m2.create(45, CV_8UC(2));


   //点的表示:Point
   Point p;
   p.x = 1//x坐标
   p.y = 1//y坐标

   //或者
   Point p2(11);

   //颜色的表示:Scalar(b,g,r);注意不是rgb,注意对应关系
   Scalar(111);

   //尺寸的表示:Size
   Size(55);// 宽度和高度都是5

   //矩形的表示:Rect,成员变量有x,y,width,height
   Rect r1(0010060);
   Rect r2(101010060);
   Rect r3 = r1 | r2; //两个矩形求交集
   Rect r4 = r1 & r2; //两个矩形求并集

   waitKey(0);

}


结束语

由于时间和文章篇幅有限,本次总结先到这里,下次小白会为小伙伴们带来OpenCV的滤波操作,各位小伙伴敬请期待。


—版权声明—

仅用于学术分享,版权属于原作者。

若有侵权,请联系微信号:yiyang-sy 删除或修改!


—THE END—
浏览 45
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报