VideoProcessToolNew.java 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. package com.izouma.awesomeadmin.util;
  2. import com.izouma.awesomeadmin.dto.VideoProcessResult;
  3. import com.izouma.awesomeadmin.service.OSSFileService;
  4. import org.apache.commons.lang3.RandomStringUtils;
  5. import org.apache.commons.lang3.StringUtils;
  6. import org.apache.commons.lang3.time.DateFormatUtils;
  7. import org.bytedeco.javacpp.indexer.UByteRawIndexer;
  8. import org.bytedeco.javacpp.opencv_imgproc;
  9. import org.bytedeco.javacpp.tesseract;
  10. import org.bytedeco.javacv.FFmpegFrameGrabber;
  11. import org.bytedeco.javacv.Frame;
  12. import org.bytedeco.javacv.FrameGrabber;
  13. import org.bytedeco.javacv.OpenCVFrameConverter;
  14. import org.hibernate.validator.internal.util.privilegedactions.GetResource;
  15. import javax.imageio.ImageIO;
  16. import java.awt.image.BufferedImage;
  17. import java.io.ByteArrayInputStream;
  18. import java.io.ByteArrayOutputStream;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.nio.ByteBuffer;
  22. import java.text.SimpleDateFormat;
  23. import java.util.*;
  24. import java.util.function.BiConsumer;
  25. import java.util.regex.Matcher;
  26. import java.util.regex.Pattern;
  27. import static org.bytedeco.javacpp.lept.pixRead;
  28. import static org.bytedeco.javacpp.opencv_core.*;
  29. import static org.bytedeco.javacpp.opencv_imgcodecs.imencode;
  30. import static org.bytedeco.javacpp.opencv_imgproc.*;
  31. import static org.bytedeco.javacpp.opencv_imgproc.bilateralFilter;
  32. import static org.bytedeco.javacpp.opencv_ml.SVM;
  33. import static org.bytedeco.javacpp.tesseract.PSM_SINGLE_LINE;
  34. public class VideoProcessToolNew {
  35. private OSSFileService ossFileService = new OSSFileService();
  36. public String imgPrefix = "/tmp/";
  37. public VideoProcessResult processVideo(String path, int frameSkip) throws FrameGrabber.Exception {
  38. SVM svm = SVM.load(GetResource.class.getClassLoader().getResource("trainneddata/pubg.xml").getPath());
  39. VideoProcessResult result = new VideoProcessResult();
  40. OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
  41. long frameCount = 0;
  42. FrameGrabber videoGrabber = new FFmpegFrameGrabber(path);
  43. videoGrabber.start();
  44. Frame vFrame;
  45. List<long[]> slices = toSlices(videoGrabber.getLengthInTime());
  46. for (long[] slice : slices) {
  47. long start = slice[0];
  48. long end = slice[1];
  49. long ts = start;
  50. videoGrabber.setTimestamp(start);
  51. while (ts <= end) {
  52. vFrame = videoGrabber.grabFrame();
  53. if (vFrame != null) {
  54. ts = vFrame.timestamp;
  55. frameCount++;
  56. if (frameCount % 200 == 0) {
  57. System.gc();
  58. }
  59. if (frameSkip > 0 && frameCount % frameSkip != 0) {
  60. continue;
  61. }
  62. Mat frame = removeBlackBarAndRotate(converterToMat.convert(vFrame));
  63. if (matchGameOver(svm, frame)) {
  64. Mat filtered = new Mat();
  65. bilateralFilter(frame, filtered, 25, 25 * 2, 25 / 2f);
  66. if (result.getRank() == null) {
  67. result.setRank(extractRank(filtered));
  68. }
  69. if (result.getTotal() == null) {
  70. result.setTotal(extractTotalNum(filtered));
  71. }
  72. if (result.getLiveTime() == null) {
  73. Map<String, Double> statistics = getStatistics(filtered);
  74. if (statistics != null) {
  75. result.setScore(statistics.get("评分"));
  76. result.setLiveTime(statistics.get("参赛时间"));
  77. // result.setKillNum(Integer.parseInt(statistics.get("淘汰").toString()));
  78. }
  79. }
  80. filtered.release();
  81. if (result.getRank() != null
  82. && result.getTotal() != null
  83. && result.getLiveTime() != null
  84. && result.getScore() != null) {
  85. try {
  86. double score = result.getScore();
  87. double total = result.getTotal();
  88. double rank = result.getRank();
  89. if (score > (total - rank) / total * 100 / 2) {
  90. String filename = "/var/samples/" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(8) + ".jpg";
  91. org.bytedeco.javacpp.opencv_imgcodecs.imwrite(filename, frame);
  92. result.setImage(uploadImage(frame));
  93. break;
  94. }
  95. } catch (Exception ignore) {
  96. }
  97. }
  98. }
  99. frame.release();
  100. System.out.println(frameCount + " frame processed");
  101. } else {
  102. break;
  103. }
  104. }
  105. if (result.isValid()) {
  106. break;
  107. }
  108. }
  109. videoGrabber.stop();
  110. videoGrabber.release();
  111. svm.deallocate();
  112. System.gc();
  113. return result.isValid() ? result : null;
  114. }
  115. public VideoProcessResult getKill3Time(String path, int frameSkip) throws FrameGrabber.Exception {
  116. SVM svm = SVM.load(GetResource.class.getClassLoader().getResource("trainneddata/pubg.xml").getPath());
  117. VideoProcessResult result = new VideoProcessResult();
  118. OpenCVFrameConverter.ToMat converterToMat = new OpenCVFrameConverter.ToMat();
  119. long frameCount = 0;
  120. FrameGrabber videoGrabber = new FFmpegFrameGrabber(path);
  121. videoGrabber.start();
  122. Frame vFrame;
  123. List<long[]> slices = toSlices(videoGrabber.getLengthInTime());
  124. for (long[] slice : slices) {
  125. long start = slice[0];
  126. long end = slice[1];
  127. long ts = start;
  128. videoGrabber.setTimestamp(start);
  129. while (ts <= end) {
  130. vFrame = videoGrabber.grabFrame();
  131. if (vFrame != null) {
  132. ts = vFrame.timestamp;
  133. frameCount++;
  134. if (frameCount % 200 == 0) {
  135. System.gc();
  136. }
  137. if (frameSkip > 0 && frameCount % frameSkip != 0) {
  138. continue;
  139. }
  140. Mat frame = removeBlackBarAndRotate(converterToMat.convert(vFrame));
  141. Mat filtered = new Mat();
  142. bilateralFilter(frame, filtered, 25, 25 * 2, 25 / 2f);
  143. if (getKillNum(filtered) >= 3) {
  144. String filename = "/var/samples/" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(8) + ".jpg";
  145. org.bytedeco.javacpp.opencv_imgcodecs.imwrite(filename, frame);
  146. result.setImage(uploadImage(frame));
  147. result.setKill3time(ts);
  148. break;
  149. }
  150. frame.release();
  151. System.out.println(frameCount + " frame processed");
  152. } else {
  153. break;
  154. }
  155. }
  156. if (result.getKill3time() != null) {
  157. break;
  158. }
  159. }
  160. videoGrabber.stop();
  161. videoGrabber.release();
  162. svm.deallocate();
  163. System.gc();
  164. return result;
  165. }
  166. private List<long[]> toSlices(Long total) {
  167. List<long[]> list = new ArrayList<>();
  168. long end = total;
  169. while (true) {
  170. long start = end - 30000000L;
  171. if (start < 0) {
  172. start = 0;
  173. }
  174. list.add(new long[]{start, end});
  175. if (start == 0) {
  176. break;
  177. }
  178. end = start - 1;
  179. }
  180. return list;
  181. }
  182. public boolean matchGameOver(SVM svm, Mat inputImage) {
  183. Mat resized = new Mat();
  184. resize(inputImage, resized, new Size(854, 480));
  185. Mat reshaped = resized.reshape(1, 1);
  186. Mat toPredict = new Mat();
  187. reshaped.convertTo(toPredict, CV_32F);
  188. float res = svm.predict(toPredict);
  189. resized.release();
  190. reshaped.release();
  191. toPredict.release();
  192. return res == 1;
  193. }
  194. public Integer extractRank(Mat src) {
  195. Integer result = null;
  196. int m = src.rows();
  197. int n = src.cols();
  198. Mat roi = new Mat(src, new Range(0, (int) (m * 0.093)), new Range((int) (n * 0.44), (int) (n * 0.56)));
  199. imwrite("rank.jpg", roi);
  200. Mat filtered = new Mat(roi.rows(), roi.cols(), CV_8UC1, new Scalar(0));
  201. Mat hsvImg = new Mat();
  202. cvtColor(roi, hsvImg, COLOR_BGR2HSV);
  203. UByteRawIndexer hsvIndexer = hsvImg.createIndexer();
  204. UByteRawIndexer filteredIndexer = filtered.createIndexer();
  205. for (int i = 0; i < roi.rows(); i++) {
  206. for (int j = 0; j < roi.cols(); j++) {
  207. int h = hsvIndexer.get(i, j, 0);
  208. int s = hsvIndexer.get(i, j, 1);
  209. int v = hsvIndexer.get(i, j, 2);
  210. int dh = 0;
  211. if (h > 26) {
  212. dh = h - 26;
  213. } else if (h < 21) {
  214. dh = 21 - h;
  215. }
  216. int ds = 0;
  217. if (s > 161) {
  218. ds = s - 161;
  219. } else if (s < 120) {
  220. ds = 120 - s;
  221. }
  222. int dv = 0;
  223. if (v > 251) {
  224. dv = v - 251;
  225. } else if (v < 238) {
  226. dv = 238 - v;
  227. }
  228. int gray = (int) (255 - Math.min(255, dh * 50)
  229. - Math.min(255, ds * 3)
  230. - Math.min(255, dv * 10));
  231. gray = gray < 0 ? 0 : gray;
  232. // int gray = (h == 26 && Math.abs(s - S) < 50) ? 255 : 0;
  233. filteredIndexer.put(i, j, gray);
  234. }
  235. }
  236. hsvIndexer.release();
  237. hsvImg.release();
  238. filteredIndexer.release();
  239. imwrite("rank_filtered.jpg", filtered);
  240. Mat gray = new Mat();
  241. adaptiveThreshold(filtered, gray, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 15, 12);
  242. imwrite("rank_gray.jpg", gray);
  243. MatVector contours = new MatVector();
  244. findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  245. List<Rect> rects = new ArrayList<>();
  246. for (int i = 0; i < contours.size(); i++) {
  247. Mat contour = contours.get(i);
  248. Rect rect = boundingRect(contour);
  249. rects.add(rect);
  250. contour.release();
  251. }
  252. rects.sort((o1, o2) -> o2.area() - o1.area());
  253. for (int i = 0; i < rects.size(); i++) {
  254. Rect rect = rects.get(i);
  255. if (i < 5) {
  256. Mat txtImg = new Mat(filtered, new Range(rect.y(), rect.y() + rect.height()), new Range(rect.x(), rect.x() + rect.width()));
  257. String str = doOCR(txtImg);
  258. txtImg.release();
  259. System.out.println(str);
  260. if (str != null) {
  261. str = str.replaceAll("[ \n.]", "");
  262. if (Pattern.matches("^第\\d{1,3}$", str)) {
  263. try {
  264. result = Integer.parseInt(str.replace("第", ""));
  265. } catch (Exception ignored) {
  266. }
  267. break;
  268. }
  269. }
  270. }
  271. }
  272. filtered.release();
  273. gray.release();
  274. roi.release();
  275. return result;
  276. }
  277. public Integer extractTotalNum(Mat src) {
  278. Integer result = null;
  279. int m = src.rows();
  280. int n = src.cols();
  281. Mat roi = new Mat(src, new Range(0, (int) (m * 0.08)), new Range((int) (n * 0.42), (int) (n * 0.58)));
  282. imwrite("total.png", roi);
  283. Mat totalFiltered = new Mat(roi.rows(), roi.cols(), CV_8UC1, new Scalar(0));
  284. Mat hsvImg = new Mat();
  285. cvtColor(roi, hsvImg, COLOR_BGR2HSV);
  286. UByteRawIndexer hsvIndexer = hsvImg.createIndexer();
  287. UByteRawIndexer resultIndexer = totalFiltered.createIndexer();
  288. for (int i = 0; i < roi.rows(); i++) {
  289. for (int j = 0; j < roi.cols(); j++) {
  290. int h = hsvIndexer.get(i, j, 0);
  291. int s = hsvIndexer.get(i, j, 1);
  292. int v = hsvIndexer.get(i, j, 2);
  293. int gray = 255 - 2 * s;
  294. gray = gray < 0 ? 0 : gray;
  295. resultIndexer.put(i, j, gray);
  296. }
  297. }
  298. hsvIndexer.release();
  299. hsvImg.release();
  300. resultIndexer.release();
  301. imwrite("total_filtered.png", totalFiltered);
  302. Mat gray = new Mat();
  303. adaptiveThreshold(totalFiltered, gray, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 15, 12);
  304. imwrite("rank_gray.jpg", gray);
  305. MatVector contours = new MatVector();
  306. findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  307. List<Rect> rects = new ArrayList<>();
  308. for (int i = 0; i < contours.size(); i++) {
  309. Mat contour = contours.get(i);
  310. Rect rect = boundingRect(contour);
  311. rects.add(rect);
  312. contour.release();
  313. }
  314. rects.sort((o1, o2) -> o2.area() - o1.area());
  315. for (int i = 0; i < rects.size(); i++) {
  316. Rect rect = rects.get(i);
  317. if (i < 5) {
  318. Mat txtImg = new Mat(totalFiltered, new Range(rect.y(), rect.y() + rect.height()), new Range(rect.x(), rect.x() + rect.width()));
  319. String str = doOCR(txtImg);
  320. txtImg.release();
  321. if (str != null) {
  322. str = str.replaceAll("[ \n]", "");
  323. if (Pattern.matches("^/\\d{1,3}$", str)) {
  324. try {
  325. result = Integer.parseInt(str.replace("/", ""));
  326. } catch (Exception ignored) {
  327. }
  328. break;
  329. }
  330. }
  331. }
  332. }
  333. totalFiltered.release();
  334. gray.release();
  335. System.out.println(result);
  336. return result;
  337. }
  338. public String extractMode(Mat src) {
  339. String result = null;
  340. int m = src.rows();
  341. int n = src.cols();
  342. Mat roi = new Mat(src, new Range(0, (int) (m * 0.065)), new Range(0, (int) (n * 0.2)));
  343. imwrite("mode.png", roi);
  344. Mat filtered = new Mat(roi.rows(), roi.cols(), CV_8UC1, new Scalar(0));
  345. Mat hsvImg = new Mat();
  346. cvtColor(roi, hsvImg, COLOR_BGR2HSV);
  347. UByteRawIndexer hsvIndexer = hsvImg.createIndexer();
  348. UByteRawIndexer bgrIndexer = roi.createIndexer();
  349. UByteRawIndexer resultIndexer = filtered.createIndexer();
  350. for (int i = 0; i < roi.rows(); i++) {
  351. for (int j = 0; j < roi.cols(); j++) {
  352. int h = hsvIndexer.get(i, j, 0);
  353. int s = hsvIndexer.get(i, j, 1);
  354. int v = hsvIndexer.get(i, j, 2);
  355. int b = bgrIndexer.get(i, j, 0);
  356. int g = bgrIndexer.get(i, j, 1);
  357. int r = bgrIndexer.get(i, j, 2);
  358. int dr = Math.abs(r - 220);
  359. int dg = Math.abs(g - 220);
  360. int db = Math.abs(b - 220);
  361. int dbgr = Math.abs(b - g) + Math.abs(b - r) + Math.abs(r - g);
  362. int gray = (int) (255 - Math.pow(dr, 2) * 0.015 - Math.pow(dg, 2) * 0.015 - Math.pow(db, 2) * 0.015 - Math.pow(dbgr, 2) * 0.015);
  363. // gray = (int) (gray / 128f * 255);
  364. // gray = 255 - Math.abs(gray - 200) * 2;
  365. if (gray > 220) {
  366. gray = 0;
  367. } else if (gray > 190) {
  368. gray = 220 - 190;
  369. } else {
  370. gray = 255;
  371. }
  372. resultIndexer.put(i, j, gray);
  373. }
  374. }
  375. hsvIndexer.release();
  376. bgrIndexer.release();
  377. hsvImg.release();
  378. resultIndexer.release();
  379. imwrite("mode_filtered.png", filtered);
  380. result = doOCR(filtered, "chi_sim");
  381. if (StringUtils.isNotEmpty(result)) {
  382. result = result.replace(" ", "").replace("\n", "");
  383. }
  384. System.out.println(result);
  385. filtered.release();
  386. roi.release();
  387. return result;
  388. }
  389. public Map<String, Double> getStatistics(Mat src) {
  390. imwrite("time.jpg", src);
  391. int m = src.rows();
  392. int n = src.cols();
  393. Mat roi = new Mat(src, new Range((int) (m * 0.569), (int) (m * 0.625)), new Range((int) (n * 0.3), (int) (n * 0.8)));
  394. Mat filtered = timeFilter(roi);
  395. imwrite("time_filtered.jpg", filtered);
  396. Map<String, String> map = new HashMap<>();
  397. Rect[] rects = {
  398. new Rect(0, 0, (int) (filtered.cols() * 0.128), filtered.rows()),
  399. // new Rect((int) (filtered.cols() * 0.128), 0, (int) (filtered.cols() * 0.128), filtered.rows()),
  400. new Rect((int) (filtered.cols() * 0.256), 0, (int) (filtered.cols() * 0.162), filtered.rows()),
  401. // new Rect((int) (filtered.cols() * 0.428), 0, (int) (filtered.cols() * 0.114), filtered.rows()),
  402. // new Rect((int) (filtered.cols() * 0.542), 0, (int) (filtered.cols() * 0.1), filtered.rows()),
  403. // new Rect((int) (filtered.cols() * 0.642), 0, (int) (filtered.cols() * 0.1), filtered.rows()),
  404. new Rect((int) (filtered.cols() * 0.742), 0, (int) (filtered.cols() * 0.15), filtered.rows())
  405. };
  406. String[] names = {
  407. "淘汰",
  408. // "伤害",
  409. "参赛时间",
  410. // "治疗量",
  411. // "救援",
  412. // "助攻",
  413. "评分"
  414. };
  415. int i = 0;
  416. for (Rect rect : rects) {
  417. Mat txtImg = new Mat(filtered, new Range(rect.y(), rect.y() + rect.height()), new Range(rect.x(), rect.x() + rect.width()));
  418. Rect rect1 = boundingRect(txtImg);
  419. int y1 = rect1.y() - 5;
  420. y1 = y1 < 0 ? 0 : y1;
  421. int y2 = rect1.y() + rect1.height() + 5;
  422. y2 = y2 > (txtImg.rows() - 1) ? (txtImg.rows() - 1) : y2;
  423. int x1 = rect1.x() - 5;
  424. x1 = x1 < 0 ? 0 : x1;
  425. int x2 = rect1.x() + rect1.width() + 5;
  426. x2 = x2 > (txtImg.cols() - 1) ? (txtImg.cols() - 1) : x2;
  427. txtImg = txtImg.rowRange(y1, y2).colRange(x1, x2);
  428. bitwise_not(txtImg, txtImg);
  429. resize(txtImg, txtImg, new Size(0, 0), 3, 3, INTER_LINEAR);
  430. String str = doOCR(txtImg);
  431. if (StringUtils.isNotEmpty(str)) {
  432. str = str.replaceAll("[ \n]", "");
  433. }
  434. map.put(names[i], str);
  435. System.out.println(names[i] + str);
  436. imwrite(names[i] + ".png", txtImg);
  437. i++;
  438. }
  439. filtered.release();
  440. roi.release();
  441. if (Pattern.matches("((^([0-9]+[.][0-9]*))|(^\\d{1,2}))分钟", map.get("参赛时间")) &&
  442. Pattern.matches("((^([0-9]+[.][0-9]+)$)|(^\\d{1,2})$)", map.get("评分"))) {
  443. try {
  444. double score = Double.parseDouble(map.get("评分"));
  445. double time = Double.parseDouble(map.get("参赛时间").replace("分钟", ""));
  446. if (score >= 0 && score <= 100 && time >= 0 && time <= 45) {
  447. Map<String, Double> result = new HashMap<>();
  448. result.put("评分", score);
  449. result.put("参赛时间", time);
  450. return result;
  451. }
  452. } catch (Exception ignored) {
  453. }
  454. }
  455. return null;
  456. }
  457. public Integer getKillNum(Mat src) {
  458. int m = src.rows();
  459. int n = src.cols();
  460. Mat roi = new Mat(src, new Range(0, (int) (m * 0.05)), new Range(0, (int) (n * 0.2)));
  461. Mat filtered1 = new Mat(roi.rows(), roi.cols(), CV_8UC3, new Scalar(0));
  462. Mat filtered2 = new Mat(roi.rows(), roi.cols(), CV_8UC1, new Scalar(0));
  463. UByteRawIndexer srcIndexer = roi.createIndexer();
  464. UByteRawIndexer idx1 = filtered1.createIndexer();
  465. UByteRawIndexer idx2 = filtered2.createIndexer();
  466. for (int i = 0; i < roi.rows(); i++) {
  467. for (int j = 0; j < roi.cols(); j++) {
  468. int b = srcIndexer.get(i, j, 0);
  469. int g = srcIndexer.get(i, j, 1);
  470. int r = srcIndexer.get(i, j, 2);
  471. // if (b > 150 & g > 150 & r > 150) {
  472. // idx1.put(i, j, (b + g + r) / 3);
  473. // } else {
  474. // idx1.put(i, j, 0);
  475. // }
  476. if (b > 190 && g > 190 & r > 190) {
  477. idx1.put(i, j, 0, b);
  478. idx1.put(i, j, 1, g);
  479. idx1.put(i, j, 2, r);
  480. } else {
  481. idx1.put(i, j, 0, 0);
  482. idx1.put(i, j, 1, 0);
  483. idx1.put(i, j, 2, 0);
  484. }
  485. int gg = (b + g + r) / 3 - 80;
  486. gg -= Math.sqrt((Math.pow(b - g, 2) + Math.pow(b - r, 2) + Math.pow(r - g, 2)) / 3);
  487. gg = Math.max(gg, 0);
  488. gg *= 1.5;
  489. gg = Math.min(gg, 255);
  490. gg = 255 - gg;
  491. idx2.put(i, j, gg);
  492. }
  493. }
  494. srcIndexer.release();
  495. idx1.release();
  496. idx2.release();
  497. cvtColor(filtered1, filtered1, COLOR_BGR2GRAY);
  498. imwrite("kill_f1.png", filtered1);
  499. imwrite("kill_f2.png", filtered2);
  500. imwrite("kill.jpg", roi);
  501. Mat gray = new Mat();
  502. threshold(filtered1, gray, 200, 255, THRESH_BINARY);
  503. filtered1.release();
  504. imwrite("kill_g.jpg", gray);
  505. dilate(gray, gray, 3);
  506. imwrite("kill_g_dilate.jpg", gray);
  507. erode(gray, gray, 1);
  508. imwrite("kill_g_erode.jpg", gray);
  509. MatVector contours = new MatVector();
  510. findContours(gray, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
  511. gray.release();
  512. List<Rect> rects = new ArrayList<>();
  513. int width = 0;
  514. int height = 0;
  515. for (int i = 0; i < contours.size(); i++) {
  516. Mat contour = contours.get(i);
  517. Rect rect = boundingRect(contour);
  518. rects.add(rect);
  519. contour.release();
  520. width += rect.width();
  521. if (rect.height() > height) {
  522. height = rect.height();
  523. }
  524. rectangle(roi, rect, new Scalar(0, 255, 0, 0));
  525. }
  526. imwrite("kill.jpg", roi);
  527. Mat img = new Mat(height, width, CV_8UC1, new Scalar(255, 255, 255, 0));
  528. int colStart = 0;
  529. rects.sort(Comparator.comparingInt(Rect::x));
  530. for (Rect rect : rects) {
  531. int rowStart = (img.rows() - rect.height()) / 2;
  532. filtered2.rowRange(new Range(rect.y(), rect.y() + rect.height()))
  533. .colRange(new Range(rect.x(), rect.x() + rect.width()))
  534. .copyTo(img.rowRange(rowStart, rowStart + rect.height())
  535. .colRange(colStart, colStart + rect.width()));
  536. colStart += rect.width();
  537. }
  538. filtered2.release();
  539. resize(img, img, new Size(width * 3, height * 3));
  540. imwrite("img.jpg", img);
  541. String str = doOCR(img);
  542. img.release();
  543. System.out.println(str);
  544. if (StringUtils.isNotEmpty(str)) {
  545. str = str.replace(" ", "");
  546. Pattern pattern = Pattern.compile("淘汰(\\d{1,2})");
  547. Matcher matcher = pattern.matcher(str);
  548. if (matcher.find()) {
  549. System.out.println(matcher.group(0));
  550. return Integer.parseInt(matcher.group(1));
  551. }
  552. }
  553. return 0;
  554. }
  555. public Mat timeFilter(Mat src) {
  556. int b = 27;
  557. int g = 145;
  558. int r = 211;
  559. int hmin = 28;
  560. int hmax = 28;
  561. int smin = 145;
  562. int smax = 145;
  563. int vmin = 160;
  564. int vmax = 160;
  565. Mat result = new Mat(src.rows(), src.cols(), CV_8UC1, new Scalar(0));
  566. Mat hsvImg = new Mat();
  567. cvtColor(src, hsvImg, COLOR_BGR2HSV);
  568. UByteRawIndexer hsvIndexer = hsvImg.createIndexer();
  569. UByteRawIndexer srcIndexer = src.createIndexer();
  570. UByteRawIndexer resultIndexer = result.createIndexer();
  571. for (int i = 0; i < src.rows(); i++) {
  572. for (int j = 0; j < src.cols(); j++) {
  573. int db = Math.abs(srcIndexer.get(i, j, 0) - b);
  574. int dg = Math.abs(srcIndexer.get(i, j, 1) - g);
  575. int dr = Math.abs(srcIndexer.get(i, j, 2) - r);
  576. int h = hsvIndexer.get(i, j, 0);
  577. int s = hsvIndexer.get(i, j, 1);
  578. int v = hsvIndexer.get(i, j, 2);
  579. int dh = h > hmax ? (h - hmax) : (h < hmin ? (hmin - h) : 0);
  580. int ds = s > smax ? (s - smax) : (s < smin ? (smin - s) : 0);
  581. int dv = v > vmax ? (v - vmax) : (v < vmin ? (vmin - v) : 0);
  582. int gray = 255 - (db * 0 + dg * 3 + dr * 2);
  583. // int gray = 255 - dh * 2 - ds * 2 - dv* 2;
  584. if (gray < 0) gray = 0;
  585. if (gray > 255) gray = 255;
  586. gray *= 1.2;
  587. if (gray > 255) gray = 255;
  588. resultIndexer.put(i, j, gray);
  589. }
  590. }
  591. hsvImg.release();
  592. hsvIndexer.release();
  593. srcIndexer.release();
  594. resultIndexer.release();
  595. return result;
  596. }
  597. private String doOCR(Mat img) {
  598. return doOCR(img, "pubg");
  599. }
  600. private String doOCR(Mat img, String lang) {
  601. imwrite("text.jpg", img);
  602. final tesseract.TessBaseAPI baseApi = new tesseract.TessBaseAPI();
  603. baseApi.Init(GetResource.class.getClassLoader().getResource("trainneddata").getPath(), lang);
  604. baseApi.SetPageSegMode(PSM_SINGLE_LINE);
  605. baseApi.SetImage(pixRead(imgPrefix + "text.jpg"));
  606. String recognizedText = baseApi.GetUTF8Text().getString();
  607. return recognizedText == null ? "" : recognizedText;
  608. }
  609. private void dilate(Mat src, Mat dst, float dilation_size) {
  610. Mat dilationElement = getStructuringElement(MORPH_ELLIPSE,
  611. new Size((int) (2 * dilation_size + 1), (int) (2 * dilation_size + 1)),
  612. new Point((int) dilation_size, (int) dilation_size));
  613. opencv_imgproc.dilate(src, dst, dilationElement);
  614. dilationElement.release();
  615. }
  616. private void erode(Mat src, Mat dst, float erosion_size) {
  617. Mat erodeElement = getStructuringElement(MORPH_RECT,
  618. new Size((int) (2 * erosion_size + 1), (int) (2 * erosion_size + 1)),
  619. new Point((int) erosion_size, (int) erosion_size));
  620. opencv_imgproc.erode(src, dst, erodeElement);
  621. erodeElement.release();
  622. }
  623. public Mat removeBlackBarAndRotate(Mat src) {
  624. if (src.cols() < src.rows()) {
  625. rotate(src, src, ROTATE_90_COUNTERCLOCKWISE);
  626. }
  627. Mat gray = new Mat();
  628. cvtColor(src, gray, COLOR_BGR2GRAY);
  629. threshold(gray, gray, 2, 255, THRESH_BINARY);
  630. Rect rect = boundingRect(gray);
  631. Mat dst = new Mat(src, new Range(rect.y(), rect.y() + rect.height()), new Range(rect.x(), rect.x() + rect.width()));
  632. src.release();
  633. gray.release();
  634. rect.deallocate();
  635. return dst;
  636. }
  637. public BufferedImage createBufferedImage(Mat mat) {
  638. ByteBuffer byteBuffer = ByteBuffer.allocate(mat.cols() * mat.rows());
  639. imencode(".jpg", mat, byteBuffer);
  640. byte[] ba = byteBuffer.array();
  641. BufferedImage bi = null;
  642. try {
  643. bi = ImageIO.read(new ByteArrayInputStream(ba));
  644. } catch (IOException e) {
  645. e.printStackTrace();
  646. }
  647. return bi;
  648. }
  649. public String uploadImage(Mat frame) {
  650. try {
  651. BufferedImage image = createBufferedImage(frame);
  652. ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
  653. ImageIO.write(image, "png", baos);//写入流中
  654. byte[] bytes = baos.toByteArray();//转换成字节
  655. InputStream in = new ByteArrayInputStream(bytes);
  656. String path = String.format("images/%s-%s.jpg", new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(new Date()), UUID.randomUUID().toString());
  657. return ossFileService.upload(in, path);
  658. } catch (IOException e) {
  659. e.printStackTrace();
  660. }
  661. return null;
  662. }
  663. private void imwrite(String name, Mat img) {
  664. org.bytedeco.javacpp.opencv_imgcodecs.imwrite(imgPrefix + name, img);
  665. }
  666. }