• 6--OpenCV:基础交互


    一、鼠标交互

    1.鼠标事件响应

    1. void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);
    2. /*******************************************************************
    3. * winname: 监听窗口名称
    4. * onMouse: 鼠标事件回调函数
    5. * userdata: 递给回调函数的可选参数
    6. *********************************************************************/

    2.鼠标事件回调函数

    1. typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
    2. //MouseCallback onMouse
    3. void onMouse(int event,int x,int y,int flag,void *param)
    4. /*******************************************************************
    5. * event: 事件类型
    6. * x: 鼠标所在图像的坐标
    7. * y:
    8. *   flags: 代表拖拽事件
    9. * param: 自己定义的onMouse事件的ID
    10. *********************************************************************/

    3.鼠标事件类型

    1. enum MouseEventTypes {
    2.       EVENT_MOUSEMOVE      = 0, //鼠标移动
    3.       EVENT_LBUTTONDOWN    = 1, //鼠标左键按下
    4.       EVENT_RBUTTONDOWN    = 2, //鼠标右键按下
    5.       EVENT_MBUTTONDOWN    = 3, //鼠标中键按下
    6.       EVENT_LBUTTONUP      = 4, //鼠标左键弹起
    7.       EVENT_RBUTTONUP      = 5, //鼠标右键弹起
    8.       EVENT_MBUTTONUP      = 6, //鼠标中键弹起
    9.       EVENT_LBUTTONDBLCLK  = 7, //鼠标左键双击
    10.       EVENT_RBUTTONDBLCLK  = 8, //鼠标右键双击
    11.       EVENT_MBUTTONDBLCLK  = 9, //鼠标中间双击
    12.       EVENT_MOUSEWHEEL     = 10, //鼠标滚轮 正数和负数分别表示向前和向后滚动
    13.       EVENT_MOUSEHWHEEL    = 11 //鼠标滚轮 正数和负数分别表示向右和向左滚动  
    14.     };

    4.鼠标拖拽类型

    1. enum MouseEventFlags {
    2.       EVENT_FLAG_LBUTTON   = 1,    //左键拖动
    3.       EVENT_FLAG_RBUTTON   = 2, //右键拖动
    4.       EVENT_FLAG_MBUTTON   = 4, //中键拖动
    5.       EVENT_FLAG_CTRLKEY   = 8, //ctr拖动
    6.       EVENT_FLAG_SHIFTKEY  = 16, //shift拖动
    7.       EVENT_FLAG_ALTKEY    = 32 //alt拖动
    8.     };

    5.☆综合代码

    注意点:

            ①将onMouse函数(回调函数)设置为类中的静态函数--->不用创建对象直接调用。

            ②onMouse(回调函数)的参数是固定的最后一个参数是void* param,此处是通过DrawShape这个类生成的对象来进行绘制操作的,所以param传入的是其生成的对象。最后在onMouse函数中第一步,就必须得强制类型转换才行

            ③namedWindow函数是用来生成一个窗口的,参数对应setMouseCallback函数的第一个参数const String& winname(窗口的名称)

            ④无需写鼠标事件响应函数的函数体(直接调用),setMouseCallback直接传参即可,注意第二个参数就是回调函数,第三个参数是param

            ⑤Rect类实例化后是一个存储矩形基本信息的对象。x,y,width,height

    1. //Opencv鼠标左键画圆,右键画方
    2. #include
    3. #include
    4. using namespace std;
    5. using namespace cv;
    6. class DrawShape
    7. {
    8. public:
    9. DrawShape() :mat(imread("mm.jpg")) {}
    10. void Show(string wName = "drawShape")
    11. {
    12. imshow(wName, mat);
    13. }
    14. void DrawCircle(int x = 300, int y = 300, int r = 10)
    15. {
    16. circle(mat, Point(x, y), r, Scalar(0, 255, 0));
    17. }
    18. void DrawRecagnle(int x = 200, int y = 200, int w = 40, int h = 40)
    19. {
    20. rectangle(mat, Rect(x, y, w, h), Scalar(255, 0, 0));
    21. }
    22. static void OnMouse(int event, int x, int y, int flag, void* param);
    23. protected:
    24. Mat mat;
    25. };
    26. void DrawShape::OnMouse(int event, int x, int y, int flag, void* param)
    27. {
    28. DrawShape* pshape = (DrawShape*)param;
    29. switch(event)
    30. {
    31. case EVENT_LBUTTONDOWN:
    32. cout << "左键按下......." << endl;
    33. pshape->DrawCircle(x,y,10);
    34. break;
    35. case EVENT_RBUTTONDOWN:
    36. cout << "右键按下......." << endl;
    37. pshape->DrawRecagnle(x-5,y-5,10,10);
    38. break;
    39. }
    40. }
    41. int main()
    42. {
    43. DrawShape* pshape = new DrawShape;
    44. namedWindow("drawShape");
    45. setMouseCallback("drawShape", &DrawShape::OnMouse, pshape);
    46. //主循环
    47. while (1)
    48. {
    49. pshape->Show();
    50. if (waitKey(10) == 27)
    51. {
    52. break;
    53. }
    54. }
    55. delete pshape;
    56. pshape = nullptr;
    57. return 0;
    58. }

    二、opencv视频操作

    opencv里对视频的编码解码等支持并不是很良好,所以不要希望用opencv 做多媒体开发,opencv是一个强大的计算机视觉库,而不是视频流编码器或者解码器。希望大家不要走入这个误区,可以把这部分简单单独看待。而且生成的视频文件不能大于2GB,而且不能添加音频。如果想搞音视频处理可以使用FFmpeg

    1.视频读取

    opencv中通过VideoCaptrue类对视频进行读取操作以及调用摄像头,类如下

    1. class VideoCapture
    2. {
    3. public:
    4.    VideoCapture();
    5.    explicit VideoCapture(const String& filename, int apiPreference = CAP_ANY);
    6.    explicit VideoCapture(const String& filename, int apiPreference, const std::vector<int>& params);
    7.    explicit VideoCapture(int index, int apiPreference = CAP_ANY);
    8.    explicit VideoCapture(int index, int apiPreference, const std::vector<int>& params);
    9.    virtual ~VideoCapture();
    10.    virtual bool open(const String& filename, int apiPreference = CAP_ANY);
    11.    virtual bool open(const String& filename, int apiPreference, const std::vector<int>& params);
    12.    virtual bool open(int index, int apiPreference = CAP_ANY);
    13.    virtual bool open(int index, int apiPreference, const std::vector<int>& params);
    14.    virtual bool isOpened() const;
    15.    virtual void release();
    16.    virtual bool grab();
    17.    virtual bool retrieve(OutputArray image, int flag = 0);
    18.    virtual VideoCapture& operator >> (CV_OUT Mat& image);
    19.    virtual VideoCapture& operator >> (CV_OUT UMat& image);
    20.    virtual bool read(OutputArray image);
    21.    virtual bool set(int propId, double value);
    22.    virtual double get(int propId) const;
    23.    String getBackendName() const;
    24.    void setExceptionMode(bool enable) { throwOnFail = enable; }
    25.    bool getExceptionMode() { return throwOnFail; }
    26.    bool waitAny(const std::vector& streams,CV_OUT std::vector<int>& readyIndex,int64 timeoutNs = 0);
    27. protected:
    28.    Ptr cap;
    29.    Ptr icap;
    30.    bool throwOnFail;
    31.    friend class internal::VideoCapturePrivateAccessor;
    32. };

    打开视频与捕获设备

    ①创建对象除了下面代码创建的方式(构造函数)以外,还可以使用内部的成员函数open函数

    参数是一个路径--->对应视频   参数若是0--->对应摄像头

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. int main()
    6. {
    7. VideoCapture cap = VideoCapture("test.mp4");
    8. if(!cap.isOpened())
    9. {
    10. cout << "打开失败!" << endl;
    11. return 0;
    12. }
    13. VideoCapture camera = VideoCapture(0);
    14. if (!camera.isOpened())
    15. {
    16. cout << "摄像头打开失败!" << endl;
    17. return 0;
    18. }
    19. return 0;
    20. }

    获取视频属性

    获得视频有诸多属性,比如:帧率、总帧数、尺寸、格式

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. int main()
    6. {
    7. VideoCapture cap = VideoCapture("test.mp4");
    8. if(!cap.isOpened())
    9. {
    10. cout << "打开失败!" << endl;
    11. return 0;
    12. }
    13. cout << "宽度:" << cap.get(CAP_PROP_FRAME_WIDTH) << endl;
    14. cout << "高度:" << cap.get(CAP_PROP_FRAME_HEIGHT) << endl;
    15. cout << "帧数:" << cap.get(CAP_PROP_FRAME_COUNT) << endl;
    16. cout << "帧率:" << cap.get(CAP_PROP_FPS) << endl;
    17. //VideoCapture camera = VideoCapture(0);
    18. //if (!camera.isOpened())
    19. //{
    20. // cout << "摄像头打开失败!" << endl;
    21. // return 0;
    22. //}
    23. return 0;
    24. }

    其他属性获取

    1. enum VideoCaptureProperties {
    2.       CAP_PROP_POS_MSEC       =0, //视频文件的当前位置,单位为毫秒  
    3.       CAP_PROP_POS_FRAMES     =1, //解码/捕获的帧的基于0的索引
    4.       CAP_PROP_POS_AVI_RATIO  =2, //视频文件的相对位置:0=影片开始,1=影片结束
    5.       CAP_PROP_FRAME_WIDTH    =3, //视频宽度
    6.       CAP_PROP_FRAME_HEIGHT   =4, //视频高度
    7.       CAP_PROP_FPS            =5, //帧率
    8.       CAP_PROP_FOURCC         =6, //4个字符的编解码器代码
    9.       CAP_PROP_FRAME_COUNT    =7, //视频文件中的帧数
    10.       CAP_PROP_FORMAT         =8, //视频格式
    11.                                  
    12.       CAP_PROP_MODE           =9,
    13.       CAP_PROP_BRIGHTNESS    =10, //图像亮度(摄像模式)
    14.       CAP_PROP_CONTRAST      =11, //图像对比度(摄像模式)
    15.       CAP_PROP_SATURATION    =12, //图像饱和度(摄像模式)
    16.       CAP_PROP_HUE           =13, //图像的色调(摄像模式)
    17.       CAP_PROP_GAIN          =14, //图像增益(摄像模式)
    18.       CAP_PROP_EXPOSURE      =15, //曝光(摄像模式)
    19.       CAP_PROP_CONVERT_RGB   =16, //图像是否应该转换为RGB的布尔标记
    20.                                  
    21.       CAP_PROP_WHITE_BALANCE_BLUE_U =17,
    22.       CAP_PROP_RECTIFICATION =18,
    23.       CAP_PROP_MONOCHROME    =19,
    24.       CAP_PROP_SHARPNESS     =20,
    25.       CAP_PROP_AUTO_EXPOSURE =21,
    26.       CAP_PROP_GAMMA         =22,
    27.       CAP_PROP_TEMPERATURE   =23,
    28.       CAP_PROP_TRIGGER       =24,
    29.       CAP_PROP_TRIGGER_DELAY =25,
    30.       CAP_PROP_WHITE_BALANCE_RED_V =26,
    31.       CAP_PROP_ZOOM          =27,
    32.       CAP_PROP_FOCUS         =28,
    33.       CAP_PROP_GUID          =29,
    34.       CAP_PROP_ISO_SPEED     =30,
    35.       CAP_PROP_BACKLIGHT     =32,
    36.       CAP_PROP_PAN           =33,
    37.       CAP_PROP_TILT          =34,
    38.       CAP_PROP_ROLL          =35,
    39.       CAP_PROP_IRIS          =36,
    40.       CAP_PROP_SETTINGS      =37,
    41.       CAP_PROP_BUFFERSIZE    =38,
    42.       CAP_PROP_AUTOFOCUS     =39,
    43.       CAP_PROP_SAR_NUM       =40,
    44.       CAP_PROP_SAR_DEN       =41,
    45.       CAP_PROP_BACKEND       =42,
    46.       CAP_PROP_CHANNEL       =43,
    47.       CAP_PROP_AUTO_WB       =44,
    48.       CAP_PROP_WB_TEMPERATURE=45,
    49.       CAP_PROP_CODEC_PIXEL_FORMAT =46,    
    50.       CAP_PROP_BITRATE       =47,
    51.       CAP_PROP_ORIENTATION_META=48,
    52.       CAP_PROP_ORIENTATION_AUTO=49,
    53.       CAP_PROP_HW_ACCELERATION=50,
    54.       CAP_PROP_HW_DEVICE      =51,
    55.       CAP_PROP_HW_ACCELERATION_USE_OPENCL=52,
    56.       CAP_PROP_OPEN_TIMEOUT_MSEC=53,
    57.       CAP_PROP_READ_TIMEOUT_MSEC=54,
    58.       CAP_PROP_STREAM_OPEN_TIME_USEC =55,
    59.       CAP_PROP_VIDEO_TOTAL_CHANNELS = 56,
    60.       CAP_PROP_VIDEO_STREAM = 57,
    61.       CAP_PROP_AUDIO_STREAM = 58,
    62.       CAP_PROP_AUDIO_POS = 59,
    63.       CAP_PROP_AUDIO_SHIFT_NSEC = 60,
    64.       CAP_PROP_AUDIO_DATA_DEPTH = 61,
    65.       CAP_PROP_AUDIO_SAMPLES_PER_SECOND = 62,
    66.       CAP_PROP_AUDIO_BASE_INDEX = 63,
    67.       CAP_PROP_AUDIO_TOTAL_CHANNELS = 64,
    68.       CAP_PROP_AUDIO_TOTAL_STREAMS = 65,
    69.       CAP_PROP_AUDIO_SYNCHRONIZE = 66,
    70.       CAP_PROP_LRF_HAS_KEY_FRAME = 67,
    71.       CAP_PROP_CODEC_EXTRADATA_INDEX = 68,
    72. #ifndef CV_DOXYGEN
    73.       CV__CAP_PROP_LATEST
    74. #endif
    75.     };

    视频转图像

    视频转图像显示

    方法:一帧一帧的流操作(已重载)即可

            (注意:流操作结束之后,原对象的相关信息都会丢失,若还要继续使用,需要重新获取。)

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. int main()
    6. {
    7. VideoCapture cap = VideoCapture("test.mp4");
    8. if(!cap.isOpened())
    9. {
    10. cout << "打开失败!" << endl;
    11. return 0;
    12. }
    13. Mat img;
    14. while (true)
    15. {
    16. cap >> img; //flip
    17. if (img.empty())
    18. {
    19. break;
    20. }
    21. imshow("图像", img);
    22. waitKey(30);
    23. }
    24. cap.release();
    25. return 0;
    26. }

    视频转图像保存(每一帧图像的保存)

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. int main()
    6. {
    7. VideoCapture cap = VideoCapture("test.mp4");
    8. if(!cap.isOpened())
    9. {
    10. cout << "打开失败!" << endl;
    11. return 0;
    12. }
    13. Mat img;
    14. int index = 1;
    15. while (true)
    16. {
    17. cap >> img; //flip
    18. if (img.empty())
    19. {
    20. break;
    21. }
    22. //imshow("图像", img);
    23. string name = "mm/img" + to_string(index++) + ".jpg";
    24. imwrite(name, img);
    25. waitKey(30);
    26. }
    27. cap.release();
    28. return 0;
    29. }

    摄像头转图像(构造函数的参数传入0即可)

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. int main()
    6. {
    7. VideoCapture cap = VideoCapture(0);
    8. if(!cap.isOpened())
    9. {
    10. cout << "打开失败!" << endl;
    11. return 0;
    12. }
    13. Mat img;
    14. int index = 1;
    15. while (true)
    16. {
    17. cap >> img;
    18. if (img.empty())
    19. {
    20. break;
    21. }
    22. imshow("图像", img);
    23. waitKey(30);
    24. }
    25. cap.release();
    26. return 0;
    27. }

    视频保存

    opencv中通过VideoWriter类对视频进行读取操作以及调用摄像头,该类的API与VideoCapture类似,该类的主要API除了构造函数外,提供了open、isOpened、release、write和重载操作符<<

    1. class CV_EXPORTS_W VideoWriter
    2. {
    3. public:
    4.    CV_WRAP VideoWriter();
    5.    CV_WRAP VideoWriter(const String& filename, int fourcc, double fps,
    6.                Size frameSize, bool isColor = true);
    7.    CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
    8.                Size frameSize, bool isColor = true);
    9.    CV_WRAP VideoWriter(const String& filename, int fourcc, double fps, const Size& frameSize,
    10.                        const std::vector<int>& params);
    11.    CV_WRAP VideoWriter(const String& filename, int apiPreference, int fourcc, double fps,
    12.                        const Size& frameSize, const std::vector<int>& params);
    13.    virtual ~VideoWriter();
    14.    CV_WRAP virtual bool open(const String& filename, int fourcc, double fps,
    15.                      Size frameSize, bool isColor = true);
    16.    CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,
    17.                      Size frameSize, bool isColor = true);
    18.    CV_WRAP bool open(const String& filename, int fourcc, double fps, const Size& frameSize,
    19.                      const std::vector<int>& params);
    20.    CV_WRAP bool open(const String& filename, int apiPreference, int fourcc, double fps,
    21.                      const Size& frameSize, const std::vector<int>& params);
    22.    CV_WRAP virtual bool isOpened() const;
    23.    CV_WRAP virtual void release();
    24.    virtual VideoWriter& operator << (const Mat& image);
    25.    virtual VideoWriter& operator << (const UMat& image);
    26.    CV_WRAP virtual void write(InputArray image);
    27.    CV_WRAP virtual bool set(int propId, double value);
    28.    CV_WRAP virtual double get(int propId) const;
    29.    CV_WRAP static int fourcc(char c1, char c2, char c3, char c4);
    30.    CV_WRAP String getBackendName() const;
    31. protected:
    32.    Ptr writer;
    33.    Ptr iwriter;
    34.    static Ptr create(const String& filename, int fourcc, double fps,
    35.                                    Size frameSize, bool isColor = true);
    36. };

     针对静态函数 fourcc函数,四个参数如何传入,见下面的网站,挑一个格式,分解成四个字符传入即可。--->常作为open的第二个参数。

    视频其他格式http://mp4ra.org/#/codecs

    摄像头转视频保存.

    ①VideoWriter的open需要四个参数:

            1)保存的路径名

            2)int fourcc--->解编码格式

            3)fps帧率

            4)Size对象(宽度和高度来构造)--->常通过get方法来获取。

    ②将在cap中         流出每一帧的图片img

                                 再流入save对象即可实现。

    1. #include
    2. #include
    3. using namespace std;
    4. using namespace cv;
    5. int main()
    6. {
    7. VideoCapture cap = VideoCapture(0);
    8. if(!cap.isOpened())
    9. {
    10. cout << "打开失败!" << endl;
    11. return 0;
    12. }
    13. int width = cap.get(CAP_PROP_FRAME_WIDTH);
    14. int height = cap.get(CAP_PROP_FRAME_HEIGHT);
    15. VideoWriter save;
    16. save.open("save.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(width, height), true);
    17. Mat img;
    18. while (true)
    19. {
    20. cap >> img;
    21. imshow("摄像头", img);
    22. save << img;
    23. //按ESC退出
    24. if (waitKey(10) == 27)
    25. {
    26. break;
    27. }
    28. }
    29. cap.release();
    30. save.release();
    31. return 0;
    32. }

    综合代码(封装成一个Video类)

    1. #include
    2. #include
    3. using namespace cv;
    4. using namespace std;
    5. class Video
    6. {
    7. public:
    8. Video();
    9. ~Video();
    10. void GetVideo(string fileName = "test.mp4");//初始化cap
    11. void SaveToVideo(string fileName = "out.avi");
    12. void SaveToImg(string preName = "mm/img");
    13. void Camera(string fileName = "录像.avi");
    14. protected:
    15. VideoCapture cap;
    16. VideoWriter save;
    17. };
    18. Video::Video()
    19. {
    20. }
    21. Video::~Video()
    22. {
    23. cap.release();
    24. save.release();
    25. }
    26. void Video::GetVideo(string fileName)
    27. {
    28. cap = VideoCapture(fileName);
    29. if (!cap.isOpened())
    30. {
    31. cout << "视频获取失败!" << endl;
    32. }
    33. }
    34. void Video::SaveToVideo(string fileName)
    35. {
    36. int w = cap.get(CAP_PROP_FRAME_WIDTH);
    37. int h = cap.get(CAP_PROP_FRAME_HEIGHT);
    38. int fps = cap.get(CAP_PROP_FPS);
    39. save.open(fileName, VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(w, h), true);
    40. Mat img;
    41. while (true)
    42. {
    43. cap >> img;
    44. if (img.empty())
    45. break;
    46. save << img;
    47. }
    48. }
    49. void Video::SaveToImg(string preName)
    50. {
    51. Mat img;
    52. int index = 0;
    53. string name;
    54. while (true)
    55. {
    56. cap >> img;
    57. if (img.empty())
    58. {
    59. break;
    60. }
    61. name = preName + to_string(index++) + ".jpg";
    62. imwrite(name, img);
    63. }
    64. }
    65. void Video::Camera(string fileName)
    66. {
    67. cap = VideoCapture(0);
    68. if (!cap.isOpened())
    69. {
    70. cout << "摄像头打开失败!" << endl;
    71. return;
    72. }
    73. int w = cap.get(CAP_PROP_FRAME_WIDTH);
    74. int h = cap.get(CAP_PROP_FRAME_HEIGHT);
    75. save.open(fileName, VideoWriter::fourcc('M', 'J', 'P', 'G'), 30, Size(w, h), true);
    76. Mat img;
    77. while (true)
    78. {
    79. cap >> img;
    80. imshow("摄像头", img);
    81. save << img;
    82. if (waitKey(10) == 27)
    83. {
    84. break;
    85. }
    86. }
    87. }
    88. int main()
    89. {
    90. Video* pvideo = new Video;
    91. pvideo->GetVideo();
    92. pvideo->SaveToImg();
    93. //刚才读到的video已经全部流出去了。
    94. pvideo->GetVideo();
    95. pvideo->SaveToVideo();
    96. pvideo->Camera();
    97. delete pvideo;
    98. return 0;
    99. }

    三、opencv滑块交互操作

    opencv滑块交互操作

    滑动条(Trackbar)是opencv动态调节参数特别好用的一种工具,虽然看起来着实有点丑

    滑动条创建函数

    1. int createTrackbar(const String& trackbarname, const String& winname,int* value, int count,TrackbarCallback onChange = 0,void* userdata = 0);
    2. /*******************************************************************
    3. * trackbarname: 滑动条名字
    4. * winname: 依附窗口名
    5. * value: 滑块位置
    6. * count: 滑块最大值(最小值是0)
    7. * onChange: 滑块回调函数
    8. * userdata: 用户回传给回调函数的数据
    9. *********************************************************************/

    滑动条回调函数

    1. typedef void (*TrackbarCallback)(int pos, void* userdata);
    2. void On_Trackbar(int pos, void* userdata);
    3. /*******************************************************************
    4. * pos:   位置
    5. * userdata: 用户回传给回调函数的数据
    6. *********************************************************************/

    ① 主要实现滑动条回调函数,然后直接调用createTrackerbar函数即可。

    ②下面主要实现,亮度条的调节滑动条---->本质上通过at函数提高每个像素点的像素值即可.

    综合代码

    1. //滑块 去操作一张图片的像素点,改变图片的连读即可
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. using namespace cv;
    7. class TrackBar
    8. {
    9. public:
    10. TrackBar() :img(imread("mm.jpg")), curBright(6), maxBright(30)
    11. {
    12. }
    13. void Show(string wName = "trackBar")
    14. {
    15. imshow(wName, img);
    16. }
    17. int*  GetData()
    18. {
    19. return &curBright;
    20. }
    21. int GetMaxBright()
    22. {
    23. return maxBright;
    24. }
    25. static void On_Trackbar(int pos, void* userdata);
    26. private:
    27. Mat img;
    28. int curBright;
    29. int maxBright;
    30. };
    31. void TrackBar::On_Trackbar(int pos, void* userdata)
    32. {
    33. TrackBar* pBar = (TrackBar*)userdata;
    34. if (!pBar->img.data)
    35. {
    36. return;
    37. }
    38. int rows = pBar->img.rows;
    39. int cols = pBar->img.cols;
    40. int dims = pBar->img.channels();
    41. cout << dims << endl;
    42. Mat mat = Mat::zeros(pBar->img.size(), pBar->img.type());
    43. float beta = 30;
    44. float alpha = 0.1f + (float)pBar->curBright / 10.0;
    45. for (int i = 0; i < rows; i++)
    46. {
    47. for (int j = 0; j < cols; j++)
    48. {
    49. if (dims == 1)
    50. {
    51. float bgr = pBar->img.at(i, j);
    52. mat.at(i, j) = saturate_cast(bgr * alpha + beta);
    53. }
    54. else if (dims == 3)
    55. {
    56. float g = pBar->img.at(i, j)[0];
    57. float b = pBar->img.at(i, j)[1];
    58. float r = pBar->img.at(i, j)[2];
    59. mat.at(i, j)[0] = saturate_cast(g * alpha + beta);
    60. mat.at(i, j)[1] = saturate_cast(b * alpha + beta);
    61. mat.at(i, j)[2] = saturate_cast(r * alpha + beta);
    62. }
    63. else
    64. return;
    65. }
    66. }
    67. imshow("trackBar", mat);
    68. }
    69. int main()
    70. {
    71. TrackBar* pBar = new TrackBar;
    72. namedWindow("trackBar");
    73. createTrackbar("亮度调整", "trackBar", pBar->GetData(), pBar->GetMaxBright(), &TrackBar::On_Trackbar, pBar);
    74. waitKey(0);
    75. return 0;
    76. }

  • 相关阅读:
    OpenSSF发布npm 最佳实践指南,应对开源依赖风险
    408 | 【2020年】计算机统考真题 自用回顾知识点整理
    java 查找英语单词相似度,用于单词匹配,法1
    C - Bound Found
    【面试题精讲】Java字符型常量和字符串常量的区别?
    webpack 面试题
    猿创征文 |《深入浅出Vue.js》打卡Day7
    多人联机之研究
    QLineEdit 使用QValidator 限制各种输入
    Webpack 5 超详细解读(一)
  • 原文地址:https://blog.csdn.net/zjjaibc/article/details/126489299