You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

RectificationController.java 12 kB

7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. package com.acts.opencv.base;
  2. import java.io.IOException;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import javax.servlet.http.HttpServletResponse;
  6. import org.opencv.core.Core;
  7. import org.opencv.core.Core.MinMaxLocResult;
  8. import org.opencv.core.CvType;
  9. import org.opencv.core.Mat;
  10. import org.opencv.core.MatOfPoint;
  11. import org.opencv.core.MatOfPoint2f;
  12. import org.opencv.core.Point;
  13. import org.opencv.core.Rect;
  14. import org.opencv.core.Scalar;
  15. import org.opencv.highgui.Highgui;
  16. import org.opencv.imgproc.Imgproc;
  17. import org.slf4j.Logger;
  18. import org.slf4j.LoggerFactory;
  19. import org.springframework.stereotype.Controller;
  20. import org.springframework.web.bind.annotation.RequestMapping;
  21. import com.acts.opencv.common.utils.Constants;
  22. import com.acts.opencv.common.utils.OpenCVUtil;
  23. import com.acts.opencv.common.web.BaseController;
  24. @Controller
  25. @RequestMapping(value = "rect")
  26. public class RectificationController extends BaseController {
  27. private static final Logger logger = LoggerFactory.getLogger(RectificationController.class);
  28. /**
  29. * 图像矫正透视变换
  30. * 创建者 Songer
  31. * 创建时间 2018年4月10日
  32. */
  33. @RequestMapping(value = "rectification")
  34. public void rectification(HttpServletResponse response, String imagefile, Integer markType) {
  35. System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  36. logger.info("\n 图像矫正透视变换");
  37. String sourcePath = Constants.PATH + imagefile;
  38. logger.info("url==============" + sourcePath);
  39. // 加载为灰度图显示
  40. Mat source1 = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR);
  41. Mat source2 = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
  42. Point anchor01 = new Point();
  43. Point anchor02 = new Point();
  44. Point anchor03 = new Point();
  45. Point anchor04 = new Point();
  46. if (markType == 1) {// 模板匹配识别定位点
  47. String matchPath = Constants.PATH + Constants.SOURCE_IMAGE_PATH + "z1_temp.png";
  48. fetchAnchorPoints1(sourcePath, matchPath, anchor01, anchor02, anchor03, anchor04);
  49. } else if (markType == 2) {// 霍夫圆检测识别定位点
  50. fetchAnchorPoints2(sourcePath, anchor01, anchor02, anchor03, anchor04);
  51. }
  52. MatOfPoint mop = new MatOfPoint(anchor01, anchor02, anchor03, anchor04);
  53. MatOfPoint2f mat2f = new MatOfPoint2f();
  54. MatOfPoint2f refmat2f = new MatOfPoint2f();
  55. mop.convertTo(mat2f, CvType.CV_32FC1);
  56. List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
  57. contours.add(mop);
  58. Core.polylines(source2, contours, true, new Scalar(0, 0, 255), 1);
  59. String destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect1.png";
  60. Highgui.imwrite(destPath, source2);
  61. // Point point11 = anchor01;
  62. // Point point12 = new Point(anchor02.x, anchor01.y);
  63. // Point point13 = new Point(anchor01.x, anchor03.y);
  64. // Point point14 = new Point(anchor02.x, anchor03.y);
  65. Point point11 = new Point(99, 200);
  66. Point point12 = new Point(2317, 200);
  67. Point point13 = new Point(99, 3300);
  68. Point point14 = new Point(2317, 3300);
  69. Mat dst_vertices = new MatOfPoint(point11, point12, point13, point14);
  70. dst_vertices.convertTo(refmat2f, CvType.CV_32FC1);
  71. Mat warpMatrix = Imgproc.getPerspectiveTransform(mat2f, refmat2f);
  72. Mat dst = new Mat(source1.rows(), source1.cols(), source1.type());
  73. System.out.println(source1.rows() + " " + source1.cols());
  74. Imgproc.warpPerspective(source1, dst, warpMatrix, dst.size(), Imgproc.INTER_LINEAR, 0,
  75. new Scalar(255, 255, 255));
  76. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect2.png";
  77. Highgui.imwrite(destPath, dst);
  78. try {
  79. byte[] imgebyte = OpenCVUtil.covertMat2Byte1(dst);
  80. renderImage(response, imgebyte);
  81. } catch (IOException e) {
  82. e.printStackTrace();
  83. }
  84. }
  85. /**
  86. * 获得锚点(定位点)
  87. * 方法1,通过模板匹配圆心,应该换成正方形也可以,之前模板匹配不行是因为模板图形不是最小的
  88. * @Author 王嵩
  89. * @param src
  90. * @param mattmp
  91. * @param anchor01
  92. * @param anchor02
  93. * @param anchor03
  94. * @param anchor04 void
  95. * @Date 2018年2月7日
  96. * 更新日志
  97. * 2018年2月7日 王嵩 首次创建
  98. *
  99. */
  100. public static void fetchAnchorPoints1(String sourcePath, String matchPath, Point anchor01, Point anchor02,
  101. Point anchor03,
  102. Point anchor04) {
  103. Mat imagematch = new Mat();
  104. Mat colorimage = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR);
  105. Point maxLoc01, maxLoc02, maxLoc03, maxLoc04;
  106. int srcRows = colorimage.rows();
  107. int srcCols = colorimage.cols();
  108. Mat src01 = colorimage.submat(new Rect(0, 0, srcCols / 2, srcRows / 2));
  109. Mat src02 = colorimage.submat(new Rect(srcCols / 2, 0, srcCols / 2, srcRows / 2));
  110. Mat src03 = colorimage.submat(new Rect(0, srcRows / 2, srcCols / 2, srcRows / 2));
  111. Mat src04 = colorimage.submat(new Rect(srcCols / 2, srcRows / 2, srcCols / 2, srcRows / 2));
  112. // Highgui.imwrite("D://ttt/t1.jpg", src01);
  113. // Highgui.imwrite("D://ttt/t2.jpg", src02);
  114. // Highgui.imwrite("D://ttt/t3.jpg", src03);
  115. // Highgui.imwrite("D://ttt/t4.jpg", src04);
  116. Mat mattmp = Highgui.imread(matchPath, Highgui.CV_LOAD_IMAGE_COLOR);
  117. Imgproc.matchTemplate(mattmp, src01, imagematch, Imgproc.TM_CCOEFF_NORMED);
  118. // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat());
  119. MinMaxLocResult minmaxLoc1 = Core.minMaxLoc(imagematch);
  120. System.out.println("minmaxLoc1.maxVal:" + minmaxLoc1.maxVal);
  121. maxLoc01 = minmaxLoc1.maxLoc;
  122. anchor01.x = maxLoc01.x;
  123. anchor01.y = maxLoc01.y;
  124. Core.circle(colorimage, maxLoc01, 3, new Scalar(0, 0, 255), 3);
  125. String destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c1.png";
  126. Highgui.imwrite(destPath, colorimage);
  127. Imgproc.matchTemplate(mattmp, src02, imagematch, Imgproc.TM_CCOEFF_NORMED);
  128. // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat());
  129. MinMaxLocResult minmaxLoc2 = Core.minMaxLoc(imagematch);
  130. System.out.println("minmaxLoc2.maxVal:" + minmaxLoc2.maxVal);
  131. maxLoc02 = minmaxLoc2.maxLoc;
  132. anchor02.x = maxLoc02.x + srcCols / 2;
  133. anchor02.y = maxLoc02.y;
  134. Core.circle(colorimage, anchor02, 3, new Scalar(0, 0, 255), 3);
  135. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c2.png";
  136. Highgui.imwrite(destPath, colorimage);
  137. Imgproc.matchTemplate(mattmp, src03, imagematch, Imgproc.TM_CCOEFF_NORMED);
  138. // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat());
  139. MinMaxLocResult minmaxLoc3 = Core.minMaxLoc(imagematch);
  140. System.out.println("minmaxLoc3.maxVal:" + minmaxLoc3.maxVal);
  141. maxLoc03 = minmaxLoc3.maxLoc;
  142. anchor03.x = maxLoc03.x;
  143. anchor03.y = maxLoc03.y + srcRows / 2;
  144. Core.circle(colorimage, anchor03, 3, new Scalar(0, 0, 255), 3);
  145. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c3.png";
  146. Highgui.imwrite(destPath, colorimage);
  147. Imgproc.matchTemplate(mattmp, src04, imagematch, Imgproc.TM_CCOEFF_NORMED);
  148. // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat());
  149. MinMaxLocResult minmaxLoc4 = Core.minMaxLoc(imagematch);
  150. System.out.println("minmaxLoc4.maxVal:" + minmaxLoc4.maxVal);
  151. maxLoc04 = minmaxLoc4.maxLoc;
  152. anchor04.x = maxLoc04.x + srcCols / 2;
  153. anchor04.y = maxLoc04.y + srcRows / 2;
  154. Core.circle(colorimage, anchor04, 3, new Scalar(0, 0, 255), 3);
  155. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c4.png";
  156. Highgui.imwrite(destPath, colorimage);
  157. }
  158. /**
  159. * 获得锚点(定位点)
  160. * 方法2,霍夫曼圆变换查找定位点
  161. * @Author 王嵩
  162. * @param src
  163. * @param mattmp
  164. * @param anchor01
  165. * @param anchor02
  166. * @param anchor03
  167. * @param anchor04 void
  168. * @Date 2018年2月7日
  169. * 更新日志
  170. * 2018年2月7日 王嵩 首次创建
  171. *
  172. */
  173. public static void fetchAnchorPoints2(String sourcePath, Point anchor01, Point anchor02, Point anchor03,
  174. Point anchor04) {
  175. Mat src = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE);
  176. Mat colorimage = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR);
  177. int srcRows = src.rows();
  178. int srcCols = src.cols();
  179. Mat source1 = src.submat(new Rect(0, 0, srcRows / 2, srcRows / 2));
  180. Mat source2 = src.submat(new Rect(srcCols / 2, 0, srcCols / 2, srcRows / 2));
  181. Mat source3 = src.submat(new Rect(0, srcRows / 2, srcCols / 2, srcRows / 2));
  182. Mat source4 = src.submat(new Rect(srcCols / 2, srcRows / 2, srcCols / 2, srcRows / 2));
  183. Mat src01 = colorimage.submat(new Rect(0, 0, srcRows / 2, srcRows / 2));
  184. Mat src02 = colorimage.submat(new Rect(srcCols / 2, 0, srcCols / 2, srcRows / 2));
  185. Mat src03 = colorimage.submat(new Rect(0, srcRows / 2, srcCols / 2, srcRows / 2));
  186. Mat src04 = colorimage.submat(new Rect(srcCols / 2, srcRows / 2, srcCols / 2, srcRows / 2));
  187. // Mat rrr = OpenCVUtil.imageBinary(src01);
  188. Mat circles = new Mat();// 声明一个向量,保存检测出的圆的圆心坐标和半径
  189. Imgproc.HoughCircles(source1, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆
  190. System.out.println("图片高 宽:" + src.rows() + " " + src.cols());
  191. System.out.println(circles.cols());
  192. int cols = circles.cols();
  193. if (cols > 0) {
  194. for (int i = 0; i < circles.cols(); i++) {
  195. double vCircle[] = circles.get(0, i);
  196. Point center = new Point(vCircle[0], vCircle[1]);
  197. int radius = (int) Math.round(vCircle[2]);
  198. Core.circle(src01, center, 3, new Scalar(0, 255, 0), -1, 8, 0);
  199. Core.circle(src01, center, radius, new Scalar(0, 0, 255), 3, 8, 0);
  200. anchor01.x = vCircle[0];
  201. anchor01.y = vCircle[1];
  202. }
  203. }
  204. String destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc1.png";
  205. Highgui.imwrite(destPath, src01);
  206. Imgproc.HoughCircles(source2, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆
  207. System.out.println(circles.cols());
  208. if (circles.cols() > 0) {
  209. for (int i = 0; i < circles.cols(); i++) {
  210. double vCircle[] = circles.get(0, i);
  211. Point center = new Point(vCircle[0], vCircle[1]);
  212. int radius = (int) Math.round(vCircle[2]);
  213. Core.circle(src02, center, 3, new Scalar(0, 255, 0), -1, 8, 0);
  214. Core.circle(src02, center, radius, new Scalar(0, 0, 255), 3, 8, 0);
  215. anchor02.x = vCircle[0] + srcCols / 2;
  216. anchor02.y = vCircle[1];
  217. }
  218. }
  219. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc2.png";
  220. Highgui.imwrite(destPath, src02);
  221. Imgproc.HoughCircles(source3, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆
  222. System.out.println(circles.cols());
  223. if (circles.cols() > 0) {
  224. for (int i = 0; i < circles.cols(); i++) {
  225. double vCircle[] = circles.get(0, i);
  226. Point center = new Point(vCircle[0], vCircle[1]);
  227. int radius = (int) Math.round(vCircle[2]);
  228. Core.circle(src03, center, 3, new Scalar(0, 255, 0), -1, 8, 0);
  229. Core.circle(src03, center, radius, new Scalar(0, 0, 255), 3, 8, 0);
  230. anchor03.x = vCircle[0];
  231. anchor03.y = vCircle[1] + srcRows / 2;
  232. }
  233. }
  234. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc3.png";
  235. Highgui.imwrite(destPath, src03);
  236. Imgproc.HoughCircles(source4, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆
  237. System.out.println(circles.cols());
  238. if (circles.cols() > 0) {
  239. for (int i = 0; i < circles.cols(); i++) {
  240. double vCircle[] = circles.get(0, i);
  241. Point center = new Point(vCircle[0], vCircle[1]);
  242. int radius = (int) Math.round(vCircle[2]);
  243. Core.circle(src04, center, 3, new Scalar(0, 255, 0), -1, 8, 0);
  244. Core.circle(src04, center, radius, new Scalar(0, 0, 255), 3, 8, 0);
  245. anchor04.x = vCircle[0] + srcCols / 2;
  246. anchor04.y = vCircle[1] + srcRows / 2;
  247. }
  248. }
  249. destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc4.png";
  250. Highgui.imwrite(destPath, src04);
  251. }
  252. }

一个基于BSD许可(开源)发行的跨平台计算机视觉库,它提供了一系列图像处理和计算机视觉方面很多通用算法。是研究图像处理技术的一个很不错的工具

Contributors (1)