建设一个公司网站,wordpress如何关闭标签功能,网站全局变量,建设银行企业网站首页#x1f506; 文章首发于我的个人博客#xff1a;欢迎大佬们来逛逛 #x1f506; OpenCV项目地址及源代码#xff1a;点击这里 文章目录 鼠标交互案例 视频读写交互视频#xff08;摄像头#xff09;转图像显示视频转图片并且保存摄像头转图片并保存 滑动条交互滑动条调整… 文章首发于我的个人博客欢迎大佬们来逛逛 OpenCV项目地址及源代码点击这里 文章目录 鼠标交互案例 视频读写交互视频摄像头转图像显示视频转图片并且保存摄像头转图片并保存 滑动条交互滑动条调整图片的亮度 鼠标交互
openCV中使用鼠标的交互的函数是setMouseCallback
可以使得激活对winname为标题的窗口进行onMouse回调函数执行的鼠标交互操作并且可以传递用户自定义变量给userdata
void setMouseCallback(const String winname, MouseCallback onMouse, void* userdata 0);
/*******************************************************************
* winname 监听窗口名称
* onMouse 鼠标事件回调函数
* userdata 递给回调函数的可选参数
*********************************************************************/关于MouseCallBack回调函数
就是一个函数指针传递的参数必须一致event鼠标点击事件 ∗ ∗ ( x , y ) ∗ ∗ **(x,y)** ∗∗(x,y)∗∗坐标flag鼠标拖拽事件void* 类型的param可以转为用户自定义变量。
typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
//MouseCallback onMouse
void onMouse(int event,int x,int y,int flag,void *param)
/*******************************************************************
* event 事件类型
* x 鼠标所在图像的坐标
* y
* flags: 代表拖拽事件
* param: 自己定义的onMouse事件的ID
*********************************************************************/关于event和flag的枚举类型
event鼠标点击
enum MouseEventTypes {EVENT_MOUSEMOVE 0, //鼠标移动EVENT_LBUTTONDOWN 1, //鼠标左键按下EVENT_RBUTTONDOWN 2, //鼠标右键按下 EVENT_MBUTTONDOWN 3, //鼠标中键按下EVENT_LBUTTONUP 4, //鼠标左键弹起EVENT_RBUTTONUP 5, //鼠标右键弹起EVENT_MBUTTONUP 6, //鼠标中键弹起EVENT_LBUTTONDBLCLK 7, //鼠标左键双击EVENT_RBUTTONDBLCLK 8, //鼠标右键双击EVENT_MBUTTONDBLCLK 9, //鼠标中间双击EVENT_MOUSEWHEEL 10, //鼠标滚轮 正数和负数分别表示向前和向后滚动EVENT_MOUSEHWHEEL 11 //鼠标滚轮 正数和负数分别表示向右和向左滚动 };flag鼠标拖拽
enum MouseEventFlags {EVENT_FLAG_LBUTTON 1, //左键拖动EVENT_FLAG_RBUTTON 2, //右键拖动EVENT_FLAG_MBUTTON 4, //中键拖动EVENT_FLAG_CTRLKEY 8, //ctr拖动EVENT_FLAG_SHIFTKEY 16, //shift拖动EVENT_FLAG_ALTKEY 32 //alt拖动};案例
在一张图片中左键点击画圆右键点击画矩形。
有关如何在openCV中绘制图形请参见
OpenCV2图像处理基础概念与操作 | HugeYlh
关键之处就是要有一个鼠标回调函数
可以声明为类的静态成员函数然后利用params进行强制转换为本类类型。
接着判断event点击的事件进行绘制即可。
static void mouseEvent(int event, int x, int y, int flag, void* params) {DrawShape* obj static_castDrawShape*(params);if (event cv::EVENT_FLAG_LBUTTON) {//左键画圆obj-drawCircle(x, y, 20);}else if (event cv::EVENT_FLAG_RBUTTON) {obj-drawRectangle(x, y, 20, 20);}}然后在主程序中我们要激活这个回调函数设置鼠标点击
其中传递回调函数要使用函数指针的形式即传递类的静态成员函数的地址。p表示我们需要传递自定义变量以便在回调函数中params转换为我们需要操作的obj
int main()
{DrawShape* p new DrawShape();//鼠标处理过程cv::namedWindow(mainWindow);//typedef void (*MouseCallback)// (int event, int x, int y, int flags, void* userdata);cv::setMouseCallback(mainWindow, DrawShape::mouseEvent, p);while (true) {p-show();if (cv::waitKey(10) 27) {break;}}delete p;p nullptr;return 0;
}完整代码参见此Github项目 视频读写交互
使用openCV做视频操作可能不会如你想象的那么容易因为openCV是一个强大的计算机视觉库而不是专注于视频操作的多媒体库。
使用openCV做视频处理不能添加音频。
也许FFmpeg 库会满足你做多媒体开发的需求。 **VideoCapture**类型对视频进行读取或者打开摄像头。
class VideoCapture
{
public:VideoCapture();explicit VideoCapture(const String filename, int apiPreference CAP_ANY);explicit VideoCapture(const String filename, int apiPreference, const std::vectorint params);explicit VideoCapture(int index, int apiPreference CAP_ANY);explicit VideoCapture(int index, int apiPreference, const std::vectorint params);virtual ~VideoCapture();virtual bool open(const String filename, int apiPreference CAP_ANY);virtual bool open(const String filename, int apiPreference, const std::vectorint params);virtual bool open(int index, int apiPreference CAP_ANY);virtual bool open(int index, int apiPreference, const std::vectorint params);virtual bool isOpened() const;virtual void release();virtual bool grab();virtual bool retrieve(OutputArray image, int flag 0);virtual VideoCapture operator (CV_OUT Mat image);virtual VideoCapture operator (CV_OUT UMat image);virtual bool read(OutputArray image);virtual bool set(int propId, double value);virtual double get(int propId) const;String getBackendName() const;void setExceptionMode(bool enable) { throwOnFail enable; }bool getExceptionMode() { return throwOnFail; }bool waitAny(const std::vectorVideoCapture streams,CV_OUT std::vectorint readyIndex,int64 timeoutNs 0);
protected:PtrCvCapture cap;PtrIVideoCapture icap;bool throwOnFail;friend class internal::VideoCapturePrivateAccessor;
};读取一个视频传递给视频的文件地址即可如果我们传递了 0则会打开摄像头如果存在否则报错
cv::VideoCapture vap(cat.MP4);if (!vap.isOpened()) {std::cout 视频打开失败!\n;return -1;}cv::VideoCapture vap2(0);if (!vap2.isOpened()) { std::cout 摄像头打开失败!\n;return;}获取基本视频中的信息get 函数
通过传递枚举类型来获取指定的信息
enum VideoCaptureProperties {CAP_PROP_POS_MSEC 0, //视频文件的当前位置单位为毫秒 CAP_PROP_POS_FRAMES 1, //解码/捕获的帧的基于0的索引CAP_PROP_POS_AVI_RATIO 2, //视频文件的相对位置:0影片开始1影片结束CAP_PROP_FRAME_WIDTH 3, //视频宽度CAP_PROP_FRAME_HEIGHT 4, //视频高度CAP_PROP_FPS 5, //帧率CAP_PROP_FOURCC 6, //4个字符的编解码器代码CAP_PROP_FRAME_COUNT 7, //视频文件中的帧数CAP_PROP_FORMAT 8, //视频格式CAP_PROP_MODE 9, CAP_PROP_BRIGHTNESS 10, //图像亮度(摄像模式)CAP_PROP_CONTRAST 11, //图像对比度(摄像模式)CAP_PROP_SATURATION 12, //图像饱和度(摄像模式)CAP_PROP_HUE 13, //图像的色调(摄像模式)CAP_PROP_GAIN 14, //图像增益(摄像模式)CAP_PROP_EXPOSURE 15, //曝光(摄像模式)CAP_PROP_CONVERT_RGB 16, //图像是否应该转换为RGB的布尔标记.......};例如
void testProerity(cv::VideoCapture vap) {std::cout 宽度: vap.get(cv::CAP_PROP_FRAME_WIDTH) \n;std::cout 高度: vap.get(cv::CAP_PROP_FRAME_HEIGHT) \n;std::cout 帧数: vap.get(cv::CAP_PROP_FRAME_COUNT) \n;std::cout 帧率: vap.get(cv::CAP_PROP_FPS) \n;
}视频摄像头转图像显示
我们加载好视频后注意到VideoCapture重载了 运算符因此可以将其重定向到一张Mat上面。
然后再一直显示这张Mat就可以做到一张一张的图片显示看起来像视频一样。
如果我们按下ESC则退出或者播放完成后图片为null了
void testCameraToImageShow(cv::VideoCapture vedio) {//显示视频cv::Mat image;while (true) {vedio image;if (image.empty() || cv::waitKey(10) 27) {break;//为null则结束}cv::imshow(cat, image);}vedio.release();
}对于摄像头的转图片显示我们只需要传递一个 VideoCapture xxx(0) 即可其他的全是一样的。 视频转图片并且保存
基本操作与上类似只不过在**imshow**的地方我们改成了保存的操作当然你也可以一边显示一边保存
保存过程imwrite函数
name第一个参数表示保存的路径传递前缀与文件名字与后缀来完成cat/1.pngimage保存的图片
void testCameraToPngImageSave(cv::VideoCapture vedio,std::string prefilename) {cv::Mat image;int index 1;while (true) {vedio image;if (image.empty() || cv::waitKey(10) 27) {break;}std::string name prefilename std::to_string(index) .png;cv::imwrite(name, image);}vedio.release();
}摄像头转图片并保存
如果是摄像头则我们不能用imwrite
有一个**VideoWriter** 提供了这样的操作通过创建一个VideoWriter类型的变量然后通过 重载往它里面写入来完成。
注意**VideoWriter** 的创建
“save.avi” 表示保存的视频路径cv::VideoWriter::fourcc(‘M’, ‘J’, ‘P’, ‘G’)视频的解码器MJPG表示mp4格式点击了解更多格式30fps帧率cv::Size(width,height)保存的尺寸大小true是否显示颜色三通道
save.open(save.avi, cv::VideoWriter::fourcc(M, J, P, G),30, cv::Size(width,height), true);具体操作如下
void CameraSave() {cv::VideoCapture cap(0);if (!cap.isOpened()) {std::cout 摄像头打开失败!\n;return;}//获取宽度和高度int width cap.get(cv::CAP_PROP_FRAME_WIDTH);int height cap.get(cv::CAP_PROP_FRAME_HEIGHT);cv::VideoWriter save{};save.open(save.avi, cv::VideoWriter::fourcc(M, J, P, G),30, cv::Size(width,height), true);cv::Mat image;while (true) {cap image;cv::imshow(摄像头, image);save image; //往流中写入if (cv::waitKey(10) 27) {break;}}cap.release();save.release();
}滑动条交互
对于滑动条交互也是和鼠标交互类似的
int createTrackbar(const String trackbarname, const String winname,int* value, int count,TrackbarCallback onChange 0,void* userdata 0);
/*******************************************************************
* trackbarname 滑动条名字
* winname 依附窗口名
* value 滑块位置
* count: 滑块最大值(最小值是0)
* onChange 滑块回调函数
* userdata 用户回传给回调函数的数据
*********************************************************************/TrackbarCallback 回调函数
typedef void (*TrackbarCallback)(int pos, void* userdata);
void On_Trackbar(int pos, void* userdata);
/*******************************************************************
* pos 位置
* userdata 用户回传给回调函数的数据
*********************************************************************/滑动条调整图片的亮度
涉及到对图片的像素操作
详细请看上节内容
OpenCV2图像处理基础概念与操作 | HugeYlh
我们规定一个初始值current和一个最大值maxValue通过调节可以调整此值
定义
一个beta表示偏移量alpha表示亮度的调整值copyMat对一个新的Mat进行像素运算操作否则无法还原。
对于三通道RGB来说
如果我们调整为最小值0 则RGB为303030此时为黑色因此beta就是我们的最小颜色值即偏移量。 然后alpha会根据我们当前滑动条的值进行调整变大。 然后执行像素运算后xxxxxxxxx就会越来越大达到亮度提高的效果。
最后显示此图像即可。 对于此回调函数的实现
//滑动条回调函数static void OnTrack(int pos,void* params){TrackBar* obj static_castTrackBar*(params);cv::Mat copyMat cv::Mat::zeros(obj-mt.size(), obj-mt.type());int dims obj-mt.channels();float beta 30, alpha 0.1 (float)pos / 10.0;for (int i 0; i obj-mt.rows; i) {for (int j 0; j obj-mt.cols; j) {if (dims 1) {uchar pix obj-mt.atuchar(i, j);copyMat.atuchar(i,j) cv::saturate_castuchar(pix * alpha beta);}else if (dims 3) {cv::Vec3b vec obj-mt.atcv::Vec3b(i, j);float b vec[0], g vec[1], r vec[2];copyMat.atcv::Vec3b(i, j)[0] cv::saturate_castuchar(b * alpha beta);copyMat.atcv::Vec3b(i, j)[1] cv::saturate_castuchar(g * alpha beta);copyMat.atcv::Vec3b(i, j)[2] cv::saturate_castuchar(r * alpha beta);}else {return;}} }cv::imshow(trackBarWindow, copyMat); //显示操作后的图像}完整代码详见Github项目源码。
https://github.com/luumod/openCV-learning-record