当前位置:   article > 正文

Qt、openCV读取摄像头,快速双边滤波实现视频流美颜、磨皮,显示_class cameratest(qmainwindow):

class cameratest(qmainwindow):

环境配置:opencv2.4.13 vs2015 Qt5.7.1

注意:

1、openCV自带的磨皮、美白效果只能进行参考,性能不高,才采用快速双边滤波

2、示例中openCV只用来打开了摄像头,可用系统自带api替代;

3、需要先编译jpeg.lib

处理步骤:

1:从摄像头抓取一帧;

2:利用libjpeg将IplImage转成jpeg;

3:快速双边滤波处理图像;

4:unsigned char *转QImage并显示;

性能参数:线程数=4 ,i5处理器, 640*480为30ms左右,fps可达30,效率非常高;

项目目的结构:

1、main.cpp

  1. #include <QtWidgets/QApplication>
  2. #include <opencv2/objdetect/objdetect.hpp>
  3. #include <opencv2/highgui/highgui.hpp>
  4. #include <opencv2/imgproc/imgproc.hpp>
  5. using namespace std;
  6. #include "cameratest.h"
  7. int main(int argc, char *argv[])
  8. {
  9. QApplication a(argc, argv);
  10. CameraTest w;
  11. w.show();
  12. return a.exec();
  13. }

2、cameratest.h cameratest.cpp cameratest.ui

  1. #ifndef CAMERATEST_H
  2. #define CAMERATEST_H
  3. #include <QtWidgets/QMainWindow>
  4. #include "ui_cameratest.h"
  5. #include "opencv2/core/core.hpp"
  6. #include "opencv2/highgui/highgui.hpp"
  7. #include "opencv2/imgproc/imgproc.hpp"
  8. #include <stdio.h>
  9. #include <opencv2/opencv.hpp>
  10. static float sigma_spatial = 0.05f;
  11. static float sigma_range = 0.05f;
  12. #define STB_IMAGE_IMPLEMENTATION
  13. #define STB_IMAGE_WRITE_IMPLEMENTATION
  14. #define _CRT_SECURE_NO_WARNINGS
  15. #include <QImage>
  16. #include <QTimer> // 设置采集数据的间隔时间
  17. #include <QSlider>
  18. using namespace cv;
  19. class CameraTest : public QMainWindow
  20. {
  21. Q_OBJECT
  22. public:
  23. CameraTest(QWidget *parent = 0);
  24. ~CameraTest();
  25. private:
  26. Ui::CameraTestClass ui;
  27. private slots:
  28. void openCamara(); // 打开摄像头
  29. void readFarme(); // 读取当前帧信息
  30. void closeCamara(); // 关闭摄像头。
  31. void horizontalSliderChanged(int);
  32. void horizontalSliderChanged2(int);
  33. private:
  34. QTimer *timer;
  35. QImage *imag;
  36. CvCapture *cam;// 视频获取结构, 用来作为视频获取函数的一个参数
  37. IplImage *frame;//申请IplImage类型指针,就是申请内存空间来存放每一帧图像
  38. };
  39. #endif // CAMERATEST_H
  1. #include "cameratest.h"
  2. #include <time.h>
  3. #include <iostream>
  4. #include "stb_image.h"
  5. #include "RBFilter_AVX2.h"
  6. #include "jpeg-9\jpeglib.h"
  7. #include "crbfilter.h"
  8. #include "stb_image_write.h"
  9. using namespace std;
  10. class TestRunTimer
  11. {
  12. clock_t begTime;
  13. public:
  14. void start() { begTime = clock(); }
  15. float elapsedTimeMS() { return float(clock() - begTime); }
  16. };
  17. unsigned char * testRunRecursiveBF_AVX2_mt(unsigned char * image, int len, int thread_count, bool multiThread = true)
  18. {
  19. int width, height, channel;
  20. unsigned char * img = stbi_load_from_memory((stbi_uc*)image, len, &width, &height, &channel, 4);
  21. if (!img)
  22. {
  23. return NULL;
  24. }
  25. channel = 4;
  26. unsigned char * img_out;
  27. if (multiThread)
  28. {
  29. CRBFilterAVX2 rbf_object;
  30. bool success = rbf_object.initialize(width, height, thread_count, false);
  31. if (!success)
  32. {
  33. delete[] img;
  34. return nullptr;
  35. }
  36. rbf_object.setSigma(sigma_spatial, sigma_range);
  37. int pitch = rbf_object.getOptimalPitch(width);
  38. img_out = (unsigned char*)_aligned_malloc(pitch * height, 32);
  39. unsigned char* buffer = (unsigned char*)_aligned_malloc(pitch * height, 32);
  40. for (int y = 0; y < height; y++)
  41. {
  42. memcpy(buffer + y * pitch, img + y * width * 4, width * 4);
  43. }
  44. delete[] img;
  45. img = buffer;
  46. success = rbf_object.filter(img_out, img, width, height, pitch);
  47. if (!success)
  48. return nullptr;
  49. }
  50. else
  51. {
  52. CRBFilter rbf_object;
  53. int pitch = rbf_object.getOptimalPitch(width);
  54. img_out = (unsigned char*)_aligned_malloc(pitch * height, 32);
  55. unsigned char* buffer = (unsigned char*)_aligned_malloc(pitch * height, 32);
  56. for (int y = 0; y < height; y++)
  57. {
  58. memcpy(buffer + y * pitch, img + y * width * 4, width * 4);
  59. }
  60. delete[] img;
  61. img = buffer;
  62. rbf_object.CRB_Filter(img, img_out, width, height, pitch, sigma_spatial, sigma_range);
  63. }
  64. _aligned_free(img);
  65. return img_out;
  66. }
  67. static bool jpegSave(const char* filename, unsigned char *outbuffer, unsigned long outlen)
  68. {
  69. FILE *f;
  70. fopen_s(&f, filename, "wb");
  71. if (!f)
  72. return false;
  73. size_t size = fwrite(outbuffer, (size_t)outlen, 1, f);
  74. fclose(f);
  75. if (size == 1)
  76. return true;
  77. return false;
  78. }
  79. /*********************************
  80. ********* IplImage转jpeg *********
  81. **********************************/
  82. static bool ipl2jpeg(IplImage *img, unsigned char **outbuffer, unsigned long outlen)
  83. {
  84. unsigned char *outdata = (uchar *)img->imageData;
  85. struct jpeg_compress_struct cinfo = { 0 };
  86. struct jpeg_error_mgr jerr;
  87. JSAMPROW row_ptr[1];
  88. int row_stride;
  89. *outbuffer = NULL;
  90. outlen = 0;
  91. cinfo.err = jpeg_std_error(&jerr);
  92. jpeg_create_compress(&cinfo);
  93. cinfo.image_width = img->width;
  94. cinfo.image_height = img->height;
  95. cinfo.input_components = img->nChannels;
  96. cinfo.in_color_space = JCS_RGB;
  97. jpeg_mem_dest(&cinfo, outbuffer, &outlen);
  98. jpeg_set_defaults(&cinfo);
  99. jpeg_start_compress(&cinfo, TRUE);
  100. row_stride = img->width * img->nChannels;
  101. while (cinfo.next_scanline < cinfo.image_height)
  102. {
  103. row_ptr[0] = &outdata[cinfo.next_scanline * row_stride];
  104. jpeg_write_scanlines(&cinfo, row_ptr, 1);
  105. }
  106. jpeg_finish_compress(&cinfo);
  107. jpeg_destroy_compress(&cinfo);
  108. return true;
  109. }
  110. CameraTest::CameraTest(QWidget *parent)
  111. : QMainWindow(parent)
  112. {
  113. ui.setupUi(this);
  114. cam = NULL;
  115. timer = new QTimer(this);
  116. imag = new QImage(); // 初始化
  117. /*信号和槽*/
  118. connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 时间到,读取当前摄像头信息
  119. connect(ui.open, SIGNAL(clicked()), this, SLOT(openCamara()));
  120. connect(ui.closeCam, SIGNAL(clicked()), this, SLOT(closeCamara()));
  121. connect(ui.horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(horizontalSliderChanged(int)));
  122. connect(ui.horizontalSlider_2, SIGNAL(valueChanged(int)), this, SLOT(horizontalSliderChanged2(int)));
  123. ui.horizontalSlider->setValue(5);
  124. ui.horizontalSlider->setMaximum(10);
  125. ui.horizontalSlider_2->setValue(5);
  126. ui.horizontalSlider_2->setMaximum(10);
  127. }
  128. void CameraTest::horizontalSliderChanged(int value)
  129. {
  130. int a = ui.horizontalSlider->value();
  131. sigma_spatial = 0.01*value;
  132. }
  133. void CameraTest::horizontalSliderChanged2(int value)
  134. {
  135. int a = ui.horizontalSlider_2->value();
  136. sigma_range = 0.01*value;
  137. }
  138. CameraTest::~CameraTest()
  139. {
  140. }
  141. void CameraTest::openCamara()
  142. {
  143. cam = cvCreateCameraCapture(0);//打开摄像头,从摄像头中获取视频
  144. timer->start(30); // 开始计时,超时则发出timeout()信号 1024/30 == fps
  145. }
  146. //
  147. //TestRunTimer timer;
  148. //timer.start();
  149. //cout << ", QImage image---time ms: " << timer.elapsedTimeMS();
  150. /*********************************
  151. ********* 读取摄像头信息 ***********
  152. **********************************/
  153. void CameraTest::readFarme()
  154. {
  155. unsigned char * buffer;
  156. unsigned long len;
  157. frame = cvQueryFrame(cam);
  158. ipl2jpeg(frame, &buffer, len);
  159. unsigned char * outImg = testRunRecursiveBF_AVX2_mt(buffer, len, 1,true);
  160. QImage image((const uchar*)outImg, frame->width, frame->height, QImage::Format_ARGB32);
  161. ui.label->setPixmap(QPixmap::fromImage(image));
  162. _aligned_free(outImg);
  163. free(buffer);
  164. }
  165. /*******************************
  166. ***关闭摄像头,释放资源,必须释放***
  167. ********************************/
  168. void CameraTest::closeCamara()
  169. {
  170. timer->stop(); // 停止读取数据。
  171. cvReleaseCapture(&cam);//释放内存;
  172. }

3、crbfilter.h crbfilter.cpp RBFilter_AVX2.h RBFilter_AVX2.cpp 参考:快速双边滤波处理算法:https://www.cnblogs.com/cpuimage/p/7629304.html

jpeg-9源码

https://download.csdn.net/download/u013495598/11078766

Qt、openCV读取摄像头,快速双边滤波实现视频流美颜、磨皮,显示demo

https://download.csdn.net/download/u013495598/11078798

也可以邮件至362168322@qq.com,发demo

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/268928
推荐阅读
相关标签
  

闽ICP备14008679号