package com.acts.opencv.base; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletResponse; import org.opencv.core.Core; import org.opencv.core.Core.MinMaxLocResult; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.MatOfPoint; import org.opencv.core.MatOfPoint2f; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.highgui.Highgui; import org.opencv.imgproc.Imgproc; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.acts.opencv.common.utils.Constants; import com.acts.opencv.common.utils.OpenCVUtil; import com.acts.opencv.common.web.BaseController; @Controller @RequestMapping(value = "rect") public class RectificationController extends BaseController { private static final Logger logger = LoggerFactory.getLogger(RectificationController.class); /** * 图像矫正透视变换 * 创建者 Songer * 创建时间 2018年4月10日 */ @RequestMapping(value = "rectification") public void rectification(HttpServletResponse response, String imagefile, Integer markType) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); logger.info("\n 图像矫正透视变换"); String sourcePath = Constants.PATH + imagefile; logger.info("url==============" + sourcePath); // 加载为灰度图显示 Mat source1 = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR); Mat source2 = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE); Point anchor01 = new Point(); Point anchor02 = new Point(); Point anchor03 = new Point(); Point anchor04 = new Point(); if (markType == 1) {// 模板匹配识别定位点 String matchPath = Constants.PATH + Constants.SOURCE_IMAGE_PATH + "z1_temp.png"; fetchAnchorPoints1(sourcePath, matchPath, anchor01, anchor02, anchor03, anchor04); } else if (markType == 2) {// 霍夫圆检测识别定位点 fetchAnchorPoints2(sourcePath, anchor01, anchor02, anchor03, anchor04); } MatOfPoint mop = new MatOfPoint(anchor01, anchor02, anchor03, anchor04); MatOfPoint2f mat2f = new MatOfPoint2f(); MatOfPoint2f refmat2f = new MatOfPoint2f(); mop.convertTo(mat2f, CvType.CV_32FC1); List contours = new ArrayList(); contours.add(mop); Core.polylines(source2, contours, true, new Scalar(0, 0, 255), 1); String destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect1.png"; Highgui.imwrite(destPath, source2); // Point point11 = anchor01; // Point point12 = new Point(anchor02.x, anchor01.y); // Point point13 = new Point(anchor01.x, anchor03.y); // Point point14 = new Point(anchor02.x, anchor03.y); Point point11 = new Point(99, 200); Point point12 = new Point(2317, 200); Point point13 = new Point(99, 3300); Point point14 = new Point(2317, 3300); Mat dst_vertices = new MatOfPoint(point11, point12, point13, point14); dst_vertices.convertTo(refmat2f, CvType.CV_32FC1); Mat warpMatrix = Imgproc.getPerspectiveTransform(mat2f, refmat2f); Mat dst = new Mat(source1.rows(), source1.cols(), source1.type()); System.out.println(source1.rows() + " " + source1.cols()); Imgproc.warpPerspective(source1, dst, warpMatrix, dst.size(), Imgproc.INTER_LINEAR, 0, new Scalar(255, 255, 255)); destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect2.png"; Highgui.imwrite(destPath, dst); try { byte[] imgebyte = OpenCVUtil.covertMat2Byte1(dst); renderImage(response, imgebyte); } catch (IOException e) { e.printStackTrace(); } } /** * 获得锚点(定位点) * 方法1,通过模板匹配圆心,应该换成正方形也可以,之前模板匹配不行是因为模板图形不是最小的 * @Author 王嵩 * @param src * @param mattmp * @param anchor01 * @param anchor02 * @param anchor03 * @param anchor04 void * @Date 2018年2月7日 * 更新日志 * 2018年2月7日 王嵩 首次创建 * */ public static void fetchAnchorPoints1(String sourcePath, String matchPath, Point anchor01, Point anchor02, Point anchor03, Point anchor04) { Mat imagematch = new Mat(); Mat colorimage = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR); Point maxLoc01, maxLoc02, maxLoc03, maxLoc04; int srcRows = colorimage.rows(); int srcCols = colorimage.cols(); Mat src01 = colorimage.submat(new Rect(0, 0, srcCols / 2, srcRows / 2)); Mat src02 = colorimage.submat(new Rect(srcCols / 2, 0, srcCols / 2, srcRows / 2)); Mat src03 = colorimage.submat(new Rect(0, srcRows / 2, srcCols / 2, srcRows / 2)); Mat src04 = colorimage.submat(new Rect(srcCols / 2, srcRows / 2, srcCols / 2, srcRows / 2)); // Highgui.imwrite("D://ttt/t1.jpg", src01); // Highgui.imwrite("D://ttt/t2.jpg", src02); // Highgui.imwrite("D://ttt/t3.jpg", src03); // Highgui.imwrite("D://ttt/t4.jpg", src04); Mat mattmp = Highgui.imread(matchPath, Highgui.CV_LOAD_IMAGE_COLOR); Imgproc.matchTemplate(mattmp, src01, imagematch, Imgproc.TM_CCOEFF_NORMED); // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat()); MinMaxLocResult minmaxLoc1 = Core.minMaxLoc(imagematch); System.out.println("minmaxLoc1.maxVal:" + minmaxLoc1.maxVal); maxLoc01 = minmaxLoc1.maxLoc; anchor01.x = maxLoc01.x; anchor01.y = maxLoc01.y; Core.circle(colorimage, maxLoc01, 3, new Scalar(0, 0, 255), 3); String destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c1.png"; Highgui.imwrite(destPath, colorimage); Imgproc.matchTemplate(mattmp, src02, imagematch, Imgproc.TM_CCOEFF_NORMED); // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat()); MinMaxLocResult minmaxLoc2 = Core.minMaxLoc(imagematch); System.out.println("minmaxLoc2.maxVal:" + minmaxLoc2.maxVal); maxLoc02 = minmaxLoc2.maxLoc; anchor02.x = maxLoc02.x + srcCols / 2; anchor02.y = maxLoc02.y; Core.circle(colorimage, anchor02, 3, new Scalar(0, 0, 255), 3); destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c2.png"; Highgui.imwrite(destPath, colorimage); Imgproc.matchTemplate(mattmp, src03, imagematch, Imgproc.TM_CCOEFF_NORMED); // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat()); MinMaxLocResult minmaxLoc3 = Core.minMaxLoc(imagematch); System.out.println("minmaxLoc3.maxVal:" + minmaxLoc3.maxVal); maxLoc03 = minmaxLoc3.maxLoc; anchor03.x = maxLoc03.x; anchor03.y = maxLoc03.y + srcRows / 2; Core.circle(colorimage, anchor03, 3, new Scalar(0, 0, 255), 3); destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c3.png"; Highgui.imwrite(destPath, colorimage); Imgproc.matchTemplate(mattmp, src04, imagematch, Imgproc.TM_CCOEFF_NORMED); // Core.normalize(imagematch, imagematch, 0, 1, Core.NORM_MINMAX, -1, new Mat()); MinMaxLocResult minmaxLoc4 = Core.minMaxLoc(imagematch); System.out.println("minmaxLoc4.maxVal:" + minmaxLoc4.maxVal); maxLoc04 = minmaxLoc4.maxLoc; anchor04.x = maxLoc04.x + srcCols / 2; anchor04.y = maxLoc04.y + srcRows / 2; Core.circle(colorimage, anchor04, 3, new Scalar(0, 0, 255), 3); destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_c4.png"; Highgui.imwrite(destPath, colorimage); } /** * 获得锚点(定位点) * 方法2,霍夫曼圆变换查找定位点 * @Author 王嵩 * @param src * @param mattmp * @param anchor01 * @param anchor02 * @param anchor03 * @param anchor04 void * @Date 2018年2月7日 * 更新日志 * 2018年2月7日 王嵩 首次创建 * */ public static void fetchAnchorPoints2(String sourcePath, Point anchor01, Point anchor02, Point anchor03, Point anchor04) { Mat src = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE); Mat colorimage = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR); int srcRows = src.rows(); int srcCols = src.cols(); Mat source1 = src.submat(new Rect(0, 0, srcRows / 2, srcRows / 2)); Mat source2 = src.submat(new Rect(srcCols / 2, 0, srcCols / 2, srcRows / 2)); Mat source3 = src.submat(new Rect(0, srcRows / 2, srcCols / 2, srcRows / 2)); Mat source4 = src.submat(new Rect(srcCols / 2, srcRows / 2, srcCols / 2, srcRows / 2)); Mat src01 = colorimage.submat(new Rect(0, 0, srcRows / 2, srcRows / 2)); Mat src02 = colorimage.submat(new Rect(srcCols / 2, 0, srcCols / 2, srcRows / 2)); Mat src03 = colorimage.submat(new Rect(0, srcRows / 2, srcCols / 2, srcRows / 2)); Mat src04 = colorimage.submat(new Rect(srcCols / 2, srcRows / 2, srcCols / 2, srcRows / 2)); // Mat rrr = OpenCVUtil.imageBinary(src01); Mat circles = new Mat();// 声明一个向量,保存检测出的圆的圆心坐标和半径 Imgproc.HoughCircles(source1, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆 System.out.println("图片高 宽:" + src.rows() + " " + src.cols()); System.out.println(circles.cols()); int cols = circles.cols(); if (cols > 0) { for (int i = 0; i < circles.cols(); i++) { double vCircle[] = circles.get(0, i); Point center = new Point(vCircle[0], vCircle[1]); int radius = (int) Math.round(vCircle[2]); Core.circle(src01, center, 3, new Scalar(0, 255, 0), -1, 8, 0); Core.circle(src01, center, radius, new Scalar(0, 0, 255), 3, 8, 0); anchor01.x = vCircle[0]; anchor01.y = vCircle[1]; } } String destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc1.png"; Highgui.imwrite(destPath, src01); Imgproc.HoughCircles(source2, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆 System.out.println(circles.cols()); if (circles.cols() > 0) { for (int i = 0; i < circles.cols(); i++) { double vCircle[] = circles.get(0, i); Point center = new Point(vCircle[0], vCircle[1]); int radius = (int) Math.round(vCircle[2]); Core.circle(src02, center, 3, new Scalar(0, 255, 0), -1, 8, 0); Core.circle(src02, center, radius, new Scalar(0, 0, 255), 3, 8, 0); anchor02.x = vCircle[0] + srcCols / 2; anchor02.y = vCircle[1]; } } destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc2.png"; Highgui.imwrite(destPath, src02); Imgproc.HoughCircles(source3, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆 System.out.println(circles.cols()); if (circles.cols() > 0) { for (int i = 0; i < circles.cols(); i++) { double vCircle[] = circles.get(0, i); Point center = new Point(vCircle[0], vCircle[1]); int radius = (int) Math.round(vCircle[2]); Core.circle(src03, center, 3, new Scalar(0, 255, 0), -1, 8, 0); Core.circle(src03, center, radius, new Scalar(0, 0, 255), 3, 8, 0); anchor03.x = vCircle[0]; anchor03.y = vCircle[1] + srcRows / 2; } } destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc3.png"; Highgui.imwrite(destPath, src03); Imgproc.HoughCircles(source4, circles, Imgproc.CV_HOUGH_GRADIENT, 1.0, 300 / 8, 200, 90, 10, 50);// 霍夫变换检测圆 System.out.println(circles.cols()); if (circles.cols() > 0) { for (int i = 0; i < circles.cols(); i++) { double vCircle[] = circles.get(0, i); Point center = new Point(vCircle[0], vCircle[1]); int radius = (int) Math.round(vCircle[2]); Core.circle(src04, center, 3, new Scalar(0, 255, 0), -1, 8, 0); Core.circle(src04, center, radius, new Scalar(0, 0, 255), 3, 8, 0); anchor04.x = vCircle[0] + srcCols / 2; anchor04.y = vCircle[1] + srcRows / 2; } } destPath = Constants.PATH + Constants.DEST_IMAGE_PATH + "rect_cc4.png"; Highgui.imwrite(destPath, src04); } }