hspscannerform.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. #include "hspscannerform.h"
  2. #include "ui_hspscannerform.h"
  3. LOG_EXTERN()
  4. HSPScannerForm::HSPScannerForm(QWidget *parent) :
  5. QWidget(parent),
  6. ui(new Ui::HSPScannerForm)
  7. {
  8. ui->setupUi(this);
  9. Qt::WindowFlags flags = windowFlags();
  10. this->setWindowFlags(flags | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
  11. m_ViewTimer = new QTimer(this);
  12. connect(m_ViewTimer, SIGNAL(timeout()), this, SLOT(onCamTimer()));
  13. m_bIsGrey = false;
  14. m_bIsOpen = m_bIsView = false;
  15. m_bIsHide = true;
  16. m_iRotate = 0;
  17. m_iScanSz = 0;
  18. m_iCamIdx = -1;
  19. SetPos(0, 0 , DEFAULT_DIALOG_WIDTH, DEFAULT_DIALOG_HEIGHT); //SetPos(1080, 0 , 384, 216);
  20. m_dA4Pos[0] = 0.07;
  21. m_dA4Pos[1] = 0.07;
  22. m_dA4Pos[2] = 0.93;
  23. m_dA4Pos[3] = 0.93;
  24. m_dIDPos[0] = 0.35;
  25. m_dIDPos[1] = 0.35;
  26. m_dIDPos[2] = 0.65;
  27. m_dIDPos[3] = 0.65;
  28. m_iCamAll[0] = DEFAULT_DIALOG_WIDTH; //DEFAULT_DIALOG_WIDTH
  29. m_iCamAll[1] = DEFAULT_DIALOG_HEIGHT;
  30. }
  31. HSPScannerForm::~HSPScannerForm()
  32. {
  33. delete ui;
  34. delete m_ViewTimer;
  35. }
  36. void HSPScannerForm::SetPos(int iX, int iY, int iW, int iH)
  37. {
  38. LOG_FUNCTION();
  39. this->move(iX, iY);
  40. ui->labViewPos->move(iX, iY);
  41. this->resize(iW, iH);
  42. ui->labViewPos->resize(iW, iH);
  43. ui->labViewPos->setAlignment(Qt::AlignCenter);
  44. QPalette label_palette;
  45. label_palette.setColor(QPalette::Background, QColor(200,200,200));
  46. ui->labViewPos->setAutoFillBackground(true);
  47. ui->labViewPos->setPalette(label_palette);
  48. }
  49. void HSPScannerForm::SetSize(float dA4[], float dID[], int iAll[])
  50. {
  51. LOG_FUNCTION();
  52. memcpy(m_dA4Pos, dA4, sizeof(m_dA4Pos));
  53. memcpy(m_dIDPos, dID, sizeof(m_dIDPos));
  54. memcpy(m_iCamAll, iAll, sizeof(m_iCamAll));
  55. }
  56. QImage HSPScannerForm::Mat2QImage(cv::Mat cvImg)
  57. {
  58. LOG_FUNCTION();
  59. QImage qImg;
  60. if(cvImg.channels() == 3) //3 channels color image
  61. {
  62. qImg = QImage((const unsigned char*)(cvImg.data),
  63. cvImg.cols, cvImg.rows,
  64. cvImg.cols * cvImg.channels(),
  65. QImage::Format_RGB888);
  66. }
  67. else if(cvImg.channels() == 1) //grayscale image
  68. {
  69. qImg = QImage((const unsigned char*)(cvImg.data),
  70. cvImg.cols, cvImg.rows,
  71. cvImg.cols * cvImg.channels(),
  72. QImage::Format_Indexed8);
  73. }
  74. else
  75. {
  76. qImg = QImage((const unsigned char*)(cvImg.data),
  77. cvImg.cols, cvImg.rows,
  78. cvImg.cols * cvImg.channels(),
  79. QImage::Format_RGB888);
  80. }
  81. return qImg.rgbSwapped();
  82. }
  83. void HSPScannerForm::onCamTimer()
  84. {
  85. LOG_FUNCTION();
  86. std::lock_guard<std::mutex> lock(m_mutex);//自动锁
  87. cv::Mat mMat1, mMat2;
  88. LogM("Read Start!");
  89. m_cvCamera.read(mMat1);
  90. //m_cvCamera >> mMat1;
  91. LogM("Read End!");
  92. cv::Size size = mMat1.size();
  93. if(mMat1.empty())
  94. {
  95. m_cvCamera.release();
  96. m_ViewTimer->stop();
  97. m_bIsView = false;
  98. }
  99. //if(mMat1.empty()) return;
  100. //灰度 mMat1-> mMat2
  101. if(m_bIsGrey)
  102. cv::cvtColor(mMat1, mMat2, cv::COLOR_RGB2GRAY);
  103. else
  104. mMat2 = mMat1;
  105. m_Capture = mMat2; //保存当前帧数据
  106. //
  107. if(m_iScanSz == 0)//HSPS_SCAN_FULL 全画幅扫描
  108. {
  109. //mMat1 = mMat2;
  110. }
  111. else if(m_iScanSz == 1)//HSPS_SCAN_A4 A4尺寸扫描
  112. {
  113. /*
  114. int _x = (int)(size.width * m_dA4Pos[0]);
  115. int _y = (int)(size.height * m_dA4Pos[1]);
  116. int _width = (int)(size.width * (m_dA4Pos[2] - m_dA4Pos[0]));
  117. int _height = (int)(size.height * (m_dA4Pos[3] - m_dA4Pos[1]));
  118. cv::Rect rA4(_x, _y, _width, _height);
  119. */
  120. cv::Rect rA4((int)(size.width * m_dA4Pos[0]), (int)(size.height * m_dA4Pos[1]),
  121. (int)(size.width * (m_dA4Pos[2] - m_dA4Pos[0])), (int)(size.height * (m_dA4Pos[3] - m_dA4Pos[1])));
  122. m_rA4 = rA4;
  123. cv::rectangle(mMat2, m_rA4, cv::Scalar(0, 255, 0)); //画长方形
  124. // mMat2 = cv::Mat(cv::Size(rA4.width, rA4.height), mMat1.type());
  125. // mMat1(rA4).convertTo(mMat2, mMat2.type(), 1, 0);
  126. }
  127. else if(m_iScanSz == 2) //HSPS_SCAN_IDCARD 身份证尺寸扫描
  128. {
  129. cv::Rect rID((int)(size.width * m_dIDPos[0]), (int)(size.height * m_dIDPos[1]),
  130. (int)(size.width * (m_dIDPos[2] - m_dIDPos[0])), (int)(size.height * (m_dIDPos[3] - m_dIDPos[1])));
  131. m_rID = rID;
  132. cv::rectangle(mMat2, m_rID, cv::Scalar(0, 255, 0)); //画长方形
  133. // mMat2 = cv::Mat(cv::Size(rID.width, rID.height), mMat1.type());
  134. // mMat1(rID).convertTo(mMat2, mMat2.type(), 1, 0);
  135. // cv::blur(mMat1, mMat2, cv::Size(rID.width, rID.height));
  136. // cv::medianBlur;
  137. }
  138. // HSPS_ROTATE_NOANGLE, // 物理环境的上方为预览窗口的上方 Positive direction. 保持最初状态不旋转
  139. // HSPS_ROTATE_LEFT, // 物理环境的左侧为预览窗口的上方 从最初状态向左旋转90度
  140. // HSPS_ROTATE_MIRROR, // 物理环境的下方为预览窗口的上方 Opposite/Nagative direction. 从最初状态向左或向右旋转180度
  141. // HSPS_ROTATE_RIGHT, // 物理环境的右侧为预览窗口的上方 从最初状态向右旋转90度
  142. // enum RotateFlags {
  143. // ROTATE_90_CLOCKWISE = 0, //!<Rotate 90 degrees clockwise 顺时针方向旋转90度
  144. // ROTATE_180 = 1, //!<Rotate 180 degrees clockwise 顺时针方向旋转180度
  145. // ROTATE_90_COUNTERCLOCKWISE = 2, //!<Rotate 270 degrees clockwise 顺时针方向旋转270度
  146. // };
  147. if(m_iRotate == 0)
  148. mMat1 = mMat2;
  149. else if(m_iRotate == 1)//从最初状态向左旋转90度,即顺时针方向旋转270度
  150. ROTATE(mMat2, mMat1, Enum_ROTATE_90_COUNTERCLOCKWISE);
  151. else if(m_iRotate == 2) //从最初状态向左或向右旋转180度
  152. ROTATE(mMat2, mMat1, Enum_ROTATE_180);
  153. else if(m_iRotate == 3) //从最初状态向右旋转90度,即顺时针方向旋转90度
  154. ROTATE(mMat2, mMat1, Enum_ROTATE_90_CLOCKWISE);
  155. if(this->isHidden()) return;
  156. QImage image = Mat2QImage(mMat1);
  157. QPixmap pixmap = QPixmap::fromImage(image);
  158. int iH = height();
  159. int iW = ((iH * pixmap.width()) / pixmap.height());
  160. QPixmap fiPixmap = pixmap.scaled(iW, iH, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  161. ui->labViewPos->setPixmap(fiPixmap);
  162. }
  163. int HSPScannerForm::GetPic(const char* sFile)
  164. {
  165. LOG_FUNCTION();
  166. LogM("GetPic(%s)", sFile);
  167. std::lock_guard<std::mutex> lock(m_mutex);//自动锁
  168. if(!m_cvCamera.isOpened()) return ERR_NOT_OPENED;
  169. if(m_Capture.empty()) return ERR_VIEW_FAIL;
  170. cv::Mat mMat1;
  171. if(m_iScanSz == 0)//HSPS_SCAN_FULL 全画幅扫描
  172. {
  173. mMat1 = m_Capture;
  174. }
  175. else if(m_iScanSz == 1)//HSPS_SCAN_A4 A4尺寸扫描
  176. {
  177. mMat1 = cv::Mat(cv::Size(m_rA4.width, m_rA4.height), m_Capture.type());
  178. m_Capture(m_rA4).convertTo(mMat1, mMat1.type(), 1, 0);
  179. }
  180. else if(m_iScanSz == 2) //HSPS_SCAN_IDCARD 身份证尺寸扫描
  181. {
  182. mMat1 = cv::Mat(cv::Size(m_rID.width, m_rID.height), m_Capture.type());
  183. m_Capture(m_rID).convertTo(mMat1, mMat1.type(), 1, 0);
  184. }
  185. if(cv::imwrite(sFile, mMat1)) //保存成文件
  186. {
  187. LogM("cv::imwrite(%s) OK!", sFile);
  188. return 0;
  189. }
  190. return ERR_VIEW_FAIL;
  191. }
  192. int HSPScannerForm::Open(const char* sID)
  193. {
  194. LOG_FUNCTION();
  195. if(m_cvCamera.isOpened()) return 0;
  196. m_iCamIdx = GetCamIndex(sID);
  197. if(m_iCamIdx < 0) return ERR_NO_DEVICE;
  198. m_cvCamera.open(m_iCamIdx);
  199. if(m_cvCamera.isOpened())
  200. {
  201. //m_cvCamera.release();
  202. m_bIsOpen = true;
  203. // m_cvCamera.set(CV_CAP_PROP_FRAME_WIDTH, 1080);//宽度
  204. // m_cvCamera.set(CV_CAP_PROP_FRAME_HEIGHT, 960);//高度
  205. // m_cvCamera.set(CV_CAP_PROP_FPS, 30);//帧率 帧/秒
  206. // m_cvCamera.set(CV_CAP_PROP_BRIGHTNESS, 1);//亮度
  207. // m_cvCamera.set(CV_CAP_PROP_CONTRAST,40);//对比度 40
  208. // m_cvCamera.set(CV_CAP_PROP_SATURATION, 50);//饱和度 50
  209. // m_cvCamera.set(CV_CAP_PROP_HUE, 50);//色调 50
  210. // m_cvCamera.set(CV_CAP_PROP_EXPOSURE, 50);//曝光 50 获取摄像头参数
  211. // double cps_FOURCC = m_cvCamera.get(CV_CAP_PROP_FOURCC);
  212. // LogD("CV_CAP_PROP_FOURCC=[%f]", cps_FOURCC);
  213. // m_cvCamera.set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
  214. double cps_W = m_cvCamera.get(cv::CAP_PROP_FRAME_WIDTH);
  215. double cps_H = m_cvCamera.get(cv::CAP_PROP_FRAME_HEIGHT);
  216. LogD("CAP_PROP_FRAME_WIDTH=[%f]", cps_W);
  217. LogD("CAP_PROP_FRAME_HEIGHT=[%f]", cps_H);
  218. return 0;
  219. }
  220. m_bIsOpen = false;
  221. return ERR_OPEN_FAIL;
  222. }
  223. int HSPScannerForm::Close()
  224. {
  225. LOG_FUNCTION();
  226. if(isVisible()) hide();
  227. if(m_cvCamera.isOpened())
  228. m_cvCamera.release();
  229. m_bIsOpen = false;
  230. return 0;
  231. }
  232. int HSPScannerForm::Preview(bool b)
  233. {
  234. LOG_FUNCTION();
  235. if(!m_bIsOpen) return ERR_NOT_OPENED;
  236. if(b)
  237. {
  238. if(!m_cvCamera.isOpened())
  239. m_cvCamera.open(m_iCamIdx);
  240. if(!m_cvCamera.isOpened())
  241. return ERR_OPEN_FAIL;
  242. m_cvCamera.set(cv::CAP_PROP_FRAME_WIDTH, m_iCamAll[0]); //
  243. m_cvCamera.set(cv::CAP_PROP_FRAME_HEIGHT, m_iCamAll[1]);
  244. double fps = m_cvCamera.get(cv::CAP_PROP_FPS); //CAP_PROP_FRAME_WIDTH CAP_PROP_FRAME_HEIGHT
  245. double cps_W = m_cvCamera.get(cv::CAP_PROP_FRAME_WIDTH);
  246. double cps_H = m_cvCamera.get(cv::CAP_PROP_FRAME_HEIGHT);
  247. LogD("CAP_PROP_FPS=[%f]", fps);
  248. LogD("CAP_PROP_FRAME_WIDTH=[%f]", cps_W);
  249. LogD("CAP_PROP_FRAME_HEIGHT=[%f]", cps_H);
  250. if(fps < 10) fps = 10;
  251. m_ViewTimer->start(int(1000/fps));
  252. m_bIsView = true;
  253. }
  254. else
  255. {
  256. m_bIsView =false;
  257. m_ViewTimer->stop();
  258. m_cvCamera.release();
  259. }
  260. return 0;
  261. }
  262. int HSPScannerForm::Show(bool b)
  263. {
  264. if(!m_bIsOpen) return ERR_NOT_OPENED;
  265. m_bIsHide = !b;
  266. if(b)
  267. this->show();
  268. else
  269. this->hide();
  270. return 0;
  271. }
  272. int HSPScannerForm::State()
  273. {
  274. return 0;
  275. }
  276. bool HSPScannerForm::GetVideoID(int iIndex, char* sGet)
  277. {
  278. char sTemp[128];
  279. sprintf(sTemp, "/sys/class/video4linux/video%d/device/modalias", iIndex);
  280. FILE* fp = fopen(sTemp, "r");
  281. if(fp == nullptr) return false;
  282. int iLen = fread(sTemp, 1, 100, fp);
  283. sTemp[iLen] = 0;
  284. fclose(fp);
  285. strcpy(sGet, sTemp);
  286. return true;
  287. }
  288. int HSPScannerForm::GetCamIndex(const char* sIn)
  289. {
  290. char sSys[128]; //usb:v04F2pB61E d0425dcE usb:v1B17p0509
  291. for(int ia = 0; ia < 10; ia++)
  292. {
  293. if(GetVideoID(ia, sSys) == false) return -1;
  294. if(memcmp(sIn, sSys, strlen(sIn)) == 0) return ia;
  295. }
  296. return -1;
  297. }
  298. /*
  299. enum RotateFlags {
  300. ROTATE_90_CLOCKWISE = 0, //!<Rotate 90 degrees clockwise
  301. ROTATE_180 = 1, //!<Rotate 180 degrees clockwise
  302. ROTATE_90_COUNTERCLOCKWISE = 2, //!<Rotate 270 degrees clockwise
  303. };
  304. */
  305. #if defined(OpenCV31)
  306. void rotate(cv::Mat src, cv::Mat& dst, int rotateCode) //
  307. {
  308. double angle = 90.0;
  309. if(rotateCode == Enum_ROTATE_90_COUNTERCLOCKWISE)//从最初状态向左旋转90度,即顺时针方向旋转270度
  310. angle = 90.0;
  311. else if(rotateCode == Enum_ROTATE_180) //从最初状态向左或向右旋转180度
  312. angle = 180.0;
  313. else if(rotateCode == Enum_ROTATE_90_CLOCKWISE) //从最初状态向右旋转90度,即顺时针方向旋转90度
  314. angle = 270.0;
  315. cv::Size src_sz = src.size();
  316. cv::Size dst_sz(src_sz.width, src_sz.height);
  317. cv::Point center = cv::Point(src.cols / 2, src.rows / 2);//旋转中心
  318. cv::Mat rot_mat = cv::getRotationMatrix2D(center, angle, 1.0);//获得仿射变换矩阵
  319. cv::warpAffine(src, dst, rot_mat, dst_sz);
  320. }
  321. #endif