OpenCV 基础入门练习

/*腐蚀模糊边缘检测读取视频、调用摄像头 */

#include "stdafx.h"

#include <opencv2/opencv.hpp>

using namespace cv;

 

int main()

{

/*  腐蚀操作

Mat img = imread("1.jpg");

imshow("picture", img);

Mat element = getStructuringElement(MORPH_ELLIPSE, Size(20, 20));

Mat dst;

erode(img, dst,element);

imshow("picture2", dst);

waitKey(0);

*/

 

/* 模糊

Mat img = imread("1.jpg");

imshow("picture", img);

Mat dst;

blur(img, dst, Size(10, 7));

imshow("picture2", dst);

waitKey(0);

*/

 

/*边缘检测

Mat img = imread("1.jpg");

imshow("picture", img);

Mat dst,edge;

cvtColor(img, dst, CV_BGR2GRAY); //转为灰度图像

blur(dst, edge, Size(3,3)); // 使用3x3内核降噪

Canny(edge, edge, 3, 9, 3); //边缘检测方法,梯度阈值3-9,算子大小3*3的矩阵

imshow("picture2", edge);

waitKey(0);

*/

 

/*读取视频

VideoCapture capture("1.avi");

while (1)

{

Mat frame;

capture >> frame;

imshow("video", frame);

waitKey(30);

}

*/

VideoCapture capture(0);

Mat edges;

while (1) {

Mat frame;

capture >> frame;

cvtColor(frame, edges, CV_BGR2GRAY);

blur(edges, edges, Size(7, 7));

Canny(edges, edges, 0, 30, 3);

imshow("摄像头", edges);

waitKey(10);

}

 

return 0;

 

}

 


/**********合成图片 *************/

int main()

{

Mat panda = imread("1.jpg");

/*namedWindow("熊猫");

imshow("熊猫", panda);*/

Mat logo = imread("logo.png");

/*namedWindow("Logo");

imshow("Logo", logo);*/

Mat imageROI;

imageROI = panda(Rect(600, 330, logo.cols, logo.rows)); //Rect前两个参数设置logo全局位置,后两个参数为logo大小

//imageROI = panda(Range(150,150+logo.rows), Range(400, 400 + logo.cols));

addWeighted(imageROI, 0.7, logo, 0.7,0.0, imageROI); //设置权重(logo透明度),微调常数,输出容器

namedWindow("合成");

imshow("合成", panda);

 

imwrite("输出图像.jpg", panda);

waitKey(0);

return 0;

}

 

 

/* 利用轨迹条控制两幅尺寸相等的图片混合*/

 

#include "stdafx.h"

#include <opencv2/opencv.hpp>

using namespace cv;

#define WINDOW_NAME "线性混合示例"

 

const int g_nMaxAlphaValue = 100; //Alpha最大值

int g_nAlphaValueSlider; //滑动条对应的变量

double g_fAlohaValue;

double g_fBetaValue;

 

//声明存储图像的变量

Mat g_srcImage1;

Mat g_srcImage2;

Mat g_dstImage;

 

/*响应滑动条的回调函数*/

void on_Trackbar(int , void * )

{

g_fAlohaValue = (float)g_nAlphaValueSlider / g_nMaxAlphaValue; //求所占比例

g_fBetaValue = (1.0 - g_fAlohaValue);

addWeighted(g_srcImage1, g_fAlohaValue, g_srcImage2, g_fBetaValue,0.0,g_dstImage);

imshow(WINDOW_NAME, g_dstImage);

}

 

int main(int argc, char **argv)

{

g_srcImage1 = imread("1.jpg");

g_srcImage2 = imread("2.jpg");

if (!g_srcImage1.data) {

printf("读取第一幅图片错误,请确定图片是否存在\n");

}

if (!g_srcImage2.data) {

printf("读取第二幅图片错误,请确定图片是否存在\n");

}

// 设置滑动条初值为70

g_nAlphaValueSlider = 60;

//创建窗体

namedWindow(WINDOW_NAME, 1);

//在创建的窗体中创建一个滑动条控件

char TrackbarName[50];

sprintf_s(TrackbarName, "透明值");

createTrackbar(TrackbarName,WINDOW_NAME,&g_nAlphaValueSlider,g_nMaxAlphaValue,on_Trackbar);

//结果在回调函数中显示

on_Trackbar(g_nAlphaValueSlider, 0);

waitKey(0);

return 0;

}

 

/* 绘画彩框 */

 

/* 绘画彩框*/

 

#include "stdafx.h"

#include <opencv2/opencv.hpp>

using namespace cv;

#define WINDOW_NAME "绘画彩框"

 

/*声明全局函数*/

void on_MouseHandle(int event, int x, int y, int flags, void *param);

void DrawRectangle(cv::Mat & img, cv::Rect box);

void ShowHelpText();

/*全局变量*/

Rect g_rectangle;

bool g_bDrawingBox = false; //是否进行绘制

RNG g_rng(12345);

 

int main(int argc, char ** argv)

{

g_rectangle = Rect(-1, -1, 0, 0);

Mat srcimage(600, 800, CV_8UC3), tempImage; //CV_8UC1,CV_8UC2,CV_8UC3分别表示1通道,2通道,3通道

srcimage.copyTo(tempImage);

g_rectangle = Rect(-1, -1, 0, 0);

srcimage = Scalar::all(255); //设置背景颜色0~255

 

namedWindow(WINDOW_NAME);

setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcimage);

/*void setMousecallback(const string& winname, MouseCallback onMouse, void* userdata=0)  

   winname:窗口的名字  

   onMouse:鼠标响应函数,回调函数。指定窗口里每次鼠标时间发生的时候,被调用的函数指针。 这个函数的原型应该为void on_Mouse(int event, int x, int y, int flags, void* param);  

   userdate:传给回调函数的参数 ,(void*)&srcimage意思为将 srcimage的地址强制转化为void*类型,即void指针类型。

 

   指针知识补充:

   void * fun( ) ; //声明一个返回值是任意类型的指针  的函数fun()

   void vfun( ) ; //声明一个没有返回值的函数vfun()

   void (*)( )  这是一种变量类型,可用来定义函数指针变量,如:

   void (*pfun)( ) ; //声明一个函数指针变量pfun,该类型函数就是void vfun( ) 这种类型,pfun可以指向这类函数,如:pfun=vfun ;

 

   参考代码:

   #include <stdio.h>

void foo( void )

{

printf("date: %s\n", __DATE__ );

}

void main()

{

void (*p)( void ) ;

     

p=foo ; //指向该函数

p();//调用方法1

(*p)(); //调用方法2

foo();

}

   

   */

 

while (1) {

/*使绘制时可看到矩阵即时拉动情况,此时实际上是在源图的基础上不断重画tempImage,而源图实际被绘制的时刻是鼠标UP时*/

srcimage.copyTo(tempImage);

if (g_bDrawingBox)DrawRectangle(tempImage, g_rectangle);

/*显示即时图像*/

imshow(WINDOW_NAME, tempImage);

if (waitKey(10) == 27)break; //等待10毫秒,在10毫秒内如果按了键盘并且按的是ascii码为27的键(ESC),则程序break。

}

return 0;

}

 

void on_MouseHandle(int event, int x, int y, int flag, void* param) {

Mat &image = *(cv::Mat*) param;

switch (event) {

case EVENT_MOUSEMOVE:

{

if (g_bDrawingBox) {

g_rectangle.width = x - g_rectangle.x;

g_rectangle.height = y - g_rectangle.y;

}

}break;

 

case EVENT_LBUTTONDOWN:

{

g_bDrawingBox = true;

g_rectangle = Rect(x, y, 0, 0); //记录起始点,

}break;

//构造函数 Rect(x,y,width,height),x, y 为左上角坐标, width, height 则为长和宽。

 

case EVENT_LBUTTONUP:

{

g_bDrawingBox = false;

/*

  书上存在下面这段代码,但实际上DrawRectangle可对width、height为负的情况处理

  Rect(x,y,width,height)中,x,y会绘制起点,DrawRectangle确定第二个点时,

  直接将x/y与width/height进行算术运算,如(7,7,-5,-5)的起始点为(2,3),第二个

  点为( 7+(-5),7+(-5) ),即(2,2),则tl为(2,2),br为(7,7)

 

  书上这段代码是为了当width/height为负时(除了往右下角方向画,必然会有负值)

  将绘制起点始终保持在矩阵的左上角(tl),且保持width/height均为正值,其实是不必要的。

 

  tempIamge没有进行此处理操作,仍然可以正常显示绘制轨迹

*/

 

/*if (g_rectangle.width < 0) {

g_rectangle.x = g_rectangle.x + g_rectangle.width;//找到鼠标松开的位置的横坐标

g_rectangle.width *= -1;

}

if (g_rectangle.height < 0) {

g_rectangle.y = g_rectangle.y + g_rectangle.height;//找到鼠标松开的位置的纵坐标

g_rectangle.height *= -1;

}*/

DrawRectangle(image, g_rectangle);

}break;

}

}

void DrawRectangle(cv::Mat &img, cv::Rect box) {

rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0, 255), g_rng.uniform(0, 255)));

}//tl- TopLeft, br- BottomRight 左上角和右下角两个点可确定一个矩阵

/*基本图形的绘制*/

 

#include "stdafx.h"

#include <opencv2/opencv.hpp>

using namespace cv;

#define WINDOW_NAME "绘画框"

#define WINDOW_WIDTH 600

 

/*   椭圆    */

void DrawEllipse(Mat img, double angle) {

int thickness = 2;

int lineType = 5;

ellipse(img, Point(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2), Point(WINDOW_WIDTH / 4, WINDOW_WIDTH / 24),

angle, 0, 360, Scalar(255, 129, 0), thickness, lineType);

}

 

/*   实心圆   */

void DrawFilledCircle(Mat img, Point center) {

int thickness = -1;

int lineType = 8;

circle(img, center, WINDOW_WIDTH / 50, Scalar(0, 0, 255), thickness, lineType);

}

 

/*   多边形   */

void DrawPolygon(Mat img) {

int lineType = 8;

Point point[1][5];

point[0][0] = Point(WINDOW_WIDTH / 4, 1 * WINDOW_WIDTH / 2);

point[0][1] = Point(3*WINDOW_WIDTH / 4, 6 * WINDOW_WIDTH / 8);

point[0][2] = Point(WINDOW_WIDTH / 2, 7 * WINDOW_WIDTH / 8);

point[0][3] = Point(2*WINDOW_WIDTH / 3, 3 * WINDOW_WIDTH / 8);

point[0][4] = Point(WINDOW_WIDTH / 4, 1 * WINDOW_WIDTH / 2);

const Point* pot[1] = { point[0] };

int npt[] = { 5 };

fillPoly(img, pot, npt,1 , Scalar(255, 255, 0), lineType);

}

 

/*    画线     */

void DrawLine(Mat img, Point start, Point end) {

int thickness = 2;

int lineType = 8;

line(img, start, end, Scalar(0, 0, 0), thickness, lineType);

}

 

int main() {

namedWindow(WINDOW_NAME);

Point center(WINDOW_WIDTH / 2, WINDOW_WIDTH / 2);

Point point(3 * WINDOW_WIDTH / 4, WINDOW_WIDTH / 2);

Mat image(WINDOW_WIDTH, WINDOW_WIDTH,CV_8UC3,Scalar(255,255,255));

DrawEllipse(image, 0);

DrawEllipse(image, 45);

DrawEllipse(image, 90);

DrawEllipse(image, -45);

DrawFilledCircle(image, center);

//DrawPolygon(image);

//DrawLine(image, center, point);

imshow(WINDOW_NAME,image );

waitKey(0);

return 0;

}

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值