- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我将使用 OpenCV 和 C++ 实现的透视校正代码转换为: https://opencv-code.com/tutorials/automatic-perspective-correction-for-quadrilateral-objects/
获取以下用Java实现的OpenCV代码:
public class project
{
static Point2f center;
public static void main(String args[])
{
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
center = new Point2f(0,0);
Mat src = new Mat();
src = Highgui.imread("image.jpg");
if(src == null)
{
System.out.println("Image not loaded");
System.exit(1);
}
Mat bw = new Mat();
Imgproc.cvtColor(src, bw, Imgproc.COLOR_BGR2GRAY);
Imgproc.blur(bw, bw, new Size(3,3));
Imgproc.Canny(bw, bw, 100, 100, 3,true);
Mat lines = new Mat();
int threshold = 70;
int minLineSize = 30;
int lineGap = 10;
Imgproc.HoughLinesP(bw, lines, 1, Math.PI / 180, threshold,
minLineSize, lineGap);
for (int x = 0; x < lines.cols(); x++)
{
double[] vec = lines.get(0, x);
double[] val = new double[4];
val[0] = 0;
val[1] = ((float) vec[1] - vec[3]) / (vec[0] - vec[2]) * -vec[0] + vec[1];
val[2] = src.cols();
val[3] = ((float) vec[1] - vec[3]) / (vec[0] - vec[2]) * (src.cols() - vec[2]) + vec[3];
lines.put(0, x, val);
}
List<Point2f> corners = new ArrayList<Point2f>();
for (int i = 0; i < lines.cols(); i++)
{
for (int j = i+1; j < lines.cols(); j++)
{
Mat m1 = null,m2 = null;
double[] d1 = lines.get(0,i);
double[] d2 = lines.get(0, j);
m1.put(0, i, d1);
m2.put(0, j, d2);
Point2f pt = computeIntersect(m1, m2);
if (pt.x >= 0 && pt.y >= 0)
corners.add(pt);
}
}
List<Point2f> approx = new ArrayList<Point2f>();
List<Point2f> curve;
MatOfPoint2f mat2f = new MatOfPoint2f();
for(int k=0;k<corners.size();++k)
{
Point2f rec = corners.get(k);
Point p = new Point(rec.x,rec.y);
mat2f.fromArray(p);
}
MatOfPoint2f mat2frec = new MatOfPoint2f();
Imgproc.approxPolyDP(mat2f, mat2frec, Imgproc.arcLength(mat2f, true) * 0.02,true);
if (approx.size() != 4)
{
System.out.println("The object is not quadrilateral!");
}
// Get mass center
for (int i = 0; i < corners.size(); i++)
{
center.x = center.x + corners.get(i).x;
center.y = center.y + corners.get(i).y;
}
center.x *= (1. / corners.size());
center.y *= (1. / corners.size());
sortCorners(corners, center);
Mat dst = src.clone();
// Draw lines
for (int i = 0; i < lines.cols(); i++)
{
double[] v = lines.get(0, i);
Scalar cc = new Scalar(0,255,0,0);
Core.line(dst, new Point(v[0], v[1]), new Point(v[2], v[3]), cc);
}
Scalar c1 = new Scalar(0,0,255,0);
Scalar c2 = new Scalar(0,255,0,0);
Scalar c3 = new Scalar(255,0,0,0);
Scalar c4 = new Scalar(255,255,255,0);
// Draw corner points
Core.circle(dst, new Point(corners.get(0).x,corners.get(0).y), 3, c1, 2);
Core.circle(dst, new Point(corners.get(1).x,corners.get(1).y), 3, c2, 2);
Core.circle(dst, new Point(corners.get(2).x,corners.get(2).y), 3, c3, 2);
Core.circle(dst, new Point(corners.get(3).x,corners.get(3).y), 3, c4, 2);
Scalar c5 = new Scalar(0,255,255,0);
// Draw mass center
Core.circle(dst, new Point(center.x,center.y), 3, c5, 2);
Mat quad = Mat.zeros(300, 220, CvType.CV_8UC3);
List<Point2f> quad_pts = new ArrayList<Point2f>();
quad_pts.add(new Point2f(0, 0));
quad_pts.add(new Point2f(quad.cols(), 0));
quad_pts.add(new Point2f(quad.cols(), quad.rows()));
quad_pts.add(new Point2f(0, quad.rows()));
Mat transmtx = Imgproc.getPerspectiveTransform((Mat) corners, (Mat) quad_pts);
Imgproc.warpPerspective(src, quad, transmtx, quad.size());
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", dst, matOfByte);
byte[] byteArray = matOfByte.toArray();
BufferedImage bufImage = null;
try
{
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
File outputfile = new File("Image.jpg");
ImageIO.write(bufImage, "jpg", outputfile);
}
catch (Exception e) {
e.printStackTrace();
}
MatOfByte matOfByte2 = new MatOfByte();
Highgui.imencode(".jpg", dst, matOfByte2);
byte[] byteArray2 = matOfByte2.toArray();
BufferedImage bufImage2 = null;
try
{
InputStream in = new ByteArrayInputStream(byteArray2);
bufImage2 = ImageIO.read(in);
File outputfile2 = new File("Quadrilateral.jpg");
ImageIO.write(bufImage, "jpg", outputfile2);
}
catch (Exception e) {
e.printStackTrace();
}
}
static Point2f computeIntersect(Mat es, Mat es2)
{
int size = (int) es.total() * es.channels();
float[] buff = new float[size];
es.get(0, 0, buff);
int size1 = (int) es.total() * es.channels();
float[] buff1 = new float[size1];
es.get(0, 0, buff1);
float x1=buff[0], y1 = buff[1], x2 = buff[2], y2 = buff[3];
float x3 = buff1[0], y3 = buff1[1], x4 = buff1[2], y4 = buff1[3];
float denom;
float d;
d = (Float) null;
d = (float)((x1 - x2) * (y3 - y4)) - ((y1 - y2) * (x3 - x4));
if (d != (Float) null)
{
Point2f pt = new Point2f();
pt.x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
pt.y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
return pt;
}
else
return new Point2f(-1, -1);
}
static void sortCorners(List<Point2f> corners,Point2f center)
{
List<Point2f> top = null, bot = null;
for (int i = 0; i < corners.size(); i++)
{
if (corners.get(i).y < center.y)
top.add(corners.get(i));
else
bot.add(corners.get(i));
}
Point2f tl = top.get(0).x > top.get(1).x ? top.get(1) : top.get(0);
Point2f tr = top.get(0).x > top.get(1).x ? top.get(0) : top.get(1);
Point2f bl = bot.get(0).x > bot.get(1).x ? bot.get(1) : bot.get(0);
Point2f br = bot.get(0).x > bot.get(1).x ? bot.get(0) : bot.get(1);
corners.clear();
corners.add(tl);
corners.add(tr);
corners.add(br);
corners.add(bl);
}
}
我在将 List
最佳答案
这是我在我的项目中使用的实现的一部分。我已经使用我开发的算法获得了确切的角点,但其余部分在此代码中给出。不要使用 point2fs。使用点数组并将它们转换为 matofpoint2fs。
可以从这里下载包含 Imshow 的 jarfile。它在任何时间点测试您的 o/p 都非常有效。将此包添加到您的程序中:https://github.com/master-atul/ImShow-Java-OpenCV
关于 approxpolydp 的详细信息: http://docs.opencv.org/java/org/opencv/imgproc/Imgproc.html#approxPolyDP%28org.opencv.core.MatOfPoint2f,org.opencv.core.MatOfPoint2f,double,boolean%29
而且您不必使用弧长。只需根据输入的清晰度给出 epsilon 的近似值即可。(例如 2.0 或 3.0..)
(sort是用来对角进行排序的函数)
int a[][],imgarr[][];
Point p[];
BufferedImage img;
int w,h;
void sort()
{
int x = (a[0][0] + a[1][0] + a[2][0] + a[3][0])/4;
int y = (a[0][1] + a[1][1] + a[2][1] + a[3][1])/4;
int j = 0;
int order[] = new int[4];
double tans[] = new double[4];
double tans1[] = new double[4];
int tmpar[][] = new int[4][2];
p = new Point[4];
for(int i = 0;i<4;i++)
{
tans1[i] = tans[i] = Math.atan2(a[i][1] - y , a[i][0] - x);//finding angles for sorting corners
}
Arrays.sort(tans1);
for(int i = 0;i<2;i++)
{
double temp = tans1[i];
tans1[i]= tans1[3-i];
tans1[3-i] = temp;
}
for(int i=0;i<4;i++)
{
for(j = 0;j<4;j++)
{
if(tans1[i]==tans[j])
break;
}
order[i] = j;
}
for(int i = 0;i<4;i++)
{
for(j=0;j<2;j++)
{
tmpar[i][j] = a[i][j];
}
}
for(int i = 0;i<4;i++)
{
for(j = 0;j<2;j++)
{
a[i][j] = tmpar[order[i]][j];
}
}
p[0] = new Point(a[0][1],a[0][0]);
p[1] = new Point(a[1][1],a[1][0]);
p[2] = new Point(a[2][1],a[2][0]);
p[3] = new Point(a[3][1],a[3][0]);
}
void transform() throws Exception
{
Point farray[] = new Point[4];
try
{
img = ImageIO.read(new File("C:/Users/Documents/a.jpg"));
}
catch(Exception r)
{
System.out.println("no file");
}
PixelGrabber pg;
if(img==null)
{
return;
}
w = img.getWidth();
h = img.getHeight();
imgarr = new int[h][w];
try
{
for(int i = 0; i < h ; i++)
{
pg = new PixelGrabber(img,0,i,w,1,imgarr[i],0,w);
pg.grabPixels();
}
changeto256();
}
catch(Exception e)
{
System.out.println("here "+e);
}
int m=0;
byte array[] = new byte[w*h];
int iar[] = new int[w*h];
for(int i = 0 ; i < h ; i++)
{
for(int j = 0 ; j < w ; j++)
{
array[m++]= (byte)imgarr[i][j];
}
}
farray[3] = new Point(0,0);
farray[0] = new Point(w,0);
farray[1] = new Point(w,h);
farray[2] = new Point(0,h);
Mat mat = new Mat(h,w, CvType.CV_8U);
mat.put(0, 0, array);
Imshow is = new Imshow("try");
MatOfPoint2f quad = new MatOfPoint2f(p);
MatOfPoint2f rect = new MatOfPoint2f(farray);
Mat transmtx = Imgproc.getPerspectiveTransform(quad,rect);
Mat output = new Mat(w,h,CvType.CV_8U);
Imgproc.warpPerspective(mat, output, transmtx, new size(w,h),Imgproc.INTER_CUBIC);
is.showImage(output);
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", output, matOfByte);
byte[] byteArray = matOfByte.toArray();
File f = new File("retrieve1.jpg");
BufferedImage img1 =null;
InputStream in = new ByteArrayInputStream(byteArray);
img1 = ImageIO.read(in);
WritableRaster raster = (WritableRaster)img1.getData();
raster.setDataElements(0,0,byteArray);
img1.setData(raster);
try
{
ImageIO.write(img1,"jpg",f);
}
catch(Exception e)
{}
}
关于JavaCV透视校正,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21571761/
我试图通过叠加更新的(更详细的)卫星图像(我从 {leaflet} 包中获取)来改善 Rayshader 的外观,但叠加层不匹配与 3D 渲染。 理想情况下,我正在寻找可以获取全局卫星图像的开源解决方
我想构建一个由单个数字组成的常量数组(1..200)来制作一个“查找表”,以将值为 1 - 200 的滚动条的位置转换为用于对图像应用 Gamma 校正的值。 第一个数组值的值在 7.0 - 9.9
我尝试对图像进行一些简单的 Gamma 校正。起初,我尝试使用 Matlab,然后将其应用于 opencv。但我得到不同的结果。下面是部分代码。代码哪里出错了? 在matlab中: for i=1:r
我使用 DirectXTex 库捕获 DX11 游戏的屏幕截图并将其保存到文件中。问题是当我将它保存为 jpeg 时效果很好,但如果我将它保存为 png 图像会变得非常明亮并被洗掉。我使用 Tweak
我正在尝试使用以下代码检测图像中ID卡的边界。关键是我使用的 Gamma 值。我使用2或3的值(假设我希望卡在背景下突出显示)。使用背景较浅或与卡片颜色本身一样浅的照片时遇到问题。请看下面的图片..第
我正在进行立体视觉设置,机翼上方安装了 2 个摄像头。左摄像头向内倾斜几度,而右摄像头与机翼平行。所有可用图像 here 然后使用(剪切和粘贴,但不按原样编译) // performing stere
我正在尝试解决有关 NFA 的问题。指令如下:字母{a, b, c}。 • L1 是最后一个字符与倒数第五个字符相同的所有字符串。例如,应该接受字符串 aaacbacbca,因为倒数第五个字符和最后一
我尝试使用 qt 更改图像的 Gamma,但没有得到理想的结果。这是我的代码: QImage Filters::aply_filtre_gamma(QImage image){ // (std:
我需要对 Y'CbCr 空间中的图像进行 Gamma 校正,以便在图像中的饱和和饥饿区域中显示细节,我想知道是否需要调整色度子 channel ? 我知道如果我让亮度 channel 像素挨饿,如果我
我不了解opencv中hog.cpp中的 Gamma 校正代码,我经历了一些链接here与opencv hog.cpp中的代码不匹配 Mat_ _lut(1, 256); const float* l
根据本页http://www.w3schools.com/cssref/css3_pr_filter.asp有对比度、亮度、色调、饱和度等。但没有明确访问 Gamma 。有没有办法用现有的 CSS3
我进行了超几何分析(使用 Python 脚本)来研究 GO-terms 在基因子集中的富集。我的输出示例如下: GO00001 1500 300 200 150 5.39198144708e-7
我使用 Opencv 编写了一个 Android 应用程序,我的图像处理算法需要对检测到的矩形进行正确的旋转,因此作为该过程的开始,我 将最大的矩形检测为 RotatedRect。 获取矩形的旋转角度
我正在使用 OpenCV 校准和校正立体声系统。我有一个眼睛会聚的立体相机,实际上我按以下顺序运行这些功能: for(int j=0; j < ChessBoard.numSquares; j++)
我会对图像使用 Gamma 校正。因此,我必须使用 G = 0.6 为源图像的每个像素强度赋值。我有问题,因为目标图像完全错误。当我从源图像中获取像素时,可能会遇到转换问题。这是我的代码: #incl
我正在构建一个 Android 应用程序,为用户提供一些图像处理功能。但在应用任何图像转换功能之前,我想进行 Gamma 校正以改善图像。我知道如何执行 Gamma 校正,但我不知道要使用什么 Gam
我在 Windows 10 上使用 SDL2 创建 OpenGL 上下文,但是当我尝试在 Intel UHD 630 上获取帧缓冲区附件颜色编码时,我收到了无效操作错误。在我的 Nvidia Gefo
我有RGB数据和Gamma校正比例 我可以用下面的来计算吗 R = pow(R, 1/Gamma) G = pow(G, 1/Gamma) B = pow(B, 1/Gamma) 或 Gamma 校正
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
自 Snow Leopard 以来,QTKit 现在从 QTMovies frameImageAtTime:withAttributes:error: 等函数返回颜色校正后的图像数据。给定未压缩的 A
我是一名优秀的程序员,十分优秀!