opencv java 倾斜矫正,OpenCV - 使用倾斜角度(倾斜)调整照片

本文介绍如何通过透视变换来校正拍摄角度导致的禅意花园图像扭曲问题。通过Python的OpenCV库,可以应用透视变换矩阵来调整图像,使其看起来更接近正方形。代码示例中展示了如何读取图像、进行变换并显示结果。读者可以通过调整变换点来优化效果。
摘要由CSDN通过智能技术生成

I have a camera pointing at a Zen Garden from above. However, the camera is fixed on the side rather than directly above the plate. As a result, the image looks like this (note the skewed shape of the rectangle):

KQ9qk.jpg

Is there a way to process the image so that the sand area can look more or less like a perfect square?

cap = cv2.VideoCapture(0)

while True:

ret, img = cap.read()

img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

img = cv2.flip(img,0)

cv2.imshow('Cropping', img)

if cv2.waitKey(500) & 0xff == 27:

cv2.destroyAllWindows()

break

Many thanks.

解决方案

You can do perspective transformation on your image. Here's a first shot that gets you in the ballpark:

import cv2

import numpy as np

img = cv2.imread('zen.jpg')

rows, cols, ch = img.shape

pts1 = np.float32(

[[cols*.25, rows*.95],

[cols*.90, rows*.95],

[cols*.10, 0],

[cols, 0]]

)

pts2 = np.float32(

[[cols*0.1, rows],

[cols, rows],

[0, 0],

[cols, 0]]

)

M = cv2.getPerspectiveTransform(pts1,pts2)

dst = cv2.warpPerspective(img, M, (cols, rows))

cv2.imshow('My Zen Garden', dst)

cv2.imwrite('zen.jpg', dst)

cv2.waitKey()

eSg5z.jpg

You can fiddle more with the numbers, but you get the idea.

Here's some online examples. The first link has a useful plot of peg points that correlate to the transformation matrix:

Java使用OpenCV矫正并截取条形码的过程通常包括以下几个步骤: 1. **图像预处理**:首先,需要对图像进行预处理,包括灰度化、二值化等操作,以便更好地识别条形码区域。 2. **边缘检测**:通过边缘检测算法(如Canny边缘检测)来找到图像中的边缘,这有助于识别条形码的轮廓。 3. **图像矫正**:利用透视变换(Perspective Transform)来矫正倾斜或扭曲的条形码图像,使得条形码区域尽可能水平且无扭曲。 4. **条形码区域定位**:根据矫正后的图像,可以通过轮廓检测找到条形码的具体位置和大小。 5. **条形码截取**:一旦定位到条形码区域,就可以将这部分图像从原图中截取出来。 6. **条形码解码**:最后,使用OpenCV中的条形码解码功能对截取的条形码图像进行解码,获取条形码中存储的信息。 以下是一个简化的代码示例,说明如何使用OpenCV进行条形码的矫正和截取: ```java import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.imgproc.Imgproc; import org.opencv.calib3d.Calib3d; // 加载OpenCV本地库 static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } public void extractBarcode(Mat src, Mat dst) { // 将图像转换为灰度图 Mat gray = new Mat(); Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY); // 应用高斯模糊 Imgproc.GaussianBlur(gray, gray, new org.opencv.core.Size(5, 5), 0); // 边缘检测 Mat edges = new Mat(); Imgproc.Canny(gray, edges, 75, 200); // 找到轮廓 List<MatOfPoint> contours = new ArrayList<>(); Mat hierarchy = new Mat(); Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); // 遍历轮廓,找到最大的轮廓(假设是条形码) MatOfPoint2f maxContour = new MatOfPoint2f(); double maxArea = 0; for (MatOfPoint contour : contours) { MatOfPoint2f contour2f = new MatOfPoint2f(contour.toArray()); double area = Imgproc.contourArea(contour); if (area > maxArea) { maxArea = area; maxContour = contour2f; } } // 如果找到了轮廓,则进行透视变换矫正 if (maxContour.rows() > 4) { // 近似轮廓 MatOfPoint2f approxCurve = new MatOfPoint2f(); Imgproc.approxPolyDP(maxContour, approxCurve, Imgproc.arcLength(maxContour, true) * 0.02, true); // 确定源点和目标点 Point[] srcPts = approxCurve.toArray(); Point[] dstPts = new Point[]{ new Point(0, 0), new Point(src.cols(), 0), new Point(src.cols(), src.rows()), new Point(0, src.rows()) }; // 计算透视变换矩阵 Mat perspectiveMatrix = Calib3d.findHomography(new MatOfPoint2f(srcPts), new MatOfPoint2f(dstPts)); // 应用透视变换 Core.perspectiveTransform(maxContour, maxContour, perspectiveMatrix); Core.perspectiveTransform(approxCurve, approxCurve, perspectiveMatrix); // 计算边界矩形并截取条形码区域 Rect rect = Imgproc.boundingRect(approxCurve); Rect rectD = new Rect(rect.x, rect.y, rect.width, rect.height); Mat barcode = new Mat(src, rectD); // 将矫正后的条形码复制到dst图像中 barcode.copyTo(dst); } else { // 如果未找到轮廓,则dst保持不变 } } // 使用示例 Mat srcImage = new Mat(...); // 加载你的图像 Mat dstImage = new Mat(srcImage.size(), CvType.CV_8UC3); extractBarcode(srcImage, dstImage); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值