Since OpenCV does not have it's own data class for Lines I guess one workaround would be to create a class similar to MatOfRect
to do the conversion. This would look sth. like:
Line.java
public class Line
{
public final Point p1;
public final Point p2;
public Line(double p1x, double p1y, double p2x, double p2y)
{
this.p1 = new Point(p1x, p1y);
this.p2 = new Point(p2x, p2y);
}
public Line(Point p1, Point p2)
{
this.p1 = p1;
this.p2 = p2;
}
public Line()
{
this(new Point(0, 0), new Point(0, 0));
}
public Line(double[] vals)
{
this();
set(vals);
}
public void set(double[] vals)
{
if (vals != null)
{
p1.x = vals.length > 0 ? vals[0] : 0;
p1.y = vals.length > 1 ? vals[1] : 0;
p2.x = vals.length > 3 ? vals[2] : 0;
p2.y = vals.length > 4 ? vals[3] : 0;
} else
{
p1.x = 0;
p1.y = 0;
p2.x = 0;
p2.y = 0;
}
}
@Override
public Line clone()
{
return new Line(p1.clone(), p2.clone());
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(p1.x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(p1.y);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(p2.x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(p2.y);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (!(obj instanceof Line))
return false;
Line it = (Line) obj;
return p1.equals(it.p1) && p2.equals(it.p2);
}
@Override
public String toString()
{
return "{" + p1.x + ", " + p1.y + ", " + p2.x + ", " + p2.y + "}";
}
}
MatOfLine.java
public class MatOfLine extends Mat
{
// 32SC4
private static final int _depth = CvType.CV_32S;
private static final int _channels = 4;
public MatOfLine()
{
super();
}
protected MatOfLine(long addr)
{
super(addr);
if (!empty() && checkVector(_channels, _depth) < 0)
throw new IllegalArgumentException("Incompatible Mat");
// FIXME: do we need release() here?
}
public static MatOfLine fromNativeAddr(long addr)
{
return new MatOfLine(addr);
}
public MatOfLine(Mat m)
{
super(m, Range.all());
if (!empty() && checkVector(_channels, _depth) < 0)
throw new IllegalArgumentException("Incompatible Mat");
// FIXME: do we need release() here?
}
public MatOfLine(Line... a)
{
super();
fromArray(a);
}
public void alloc(int elemNumber)
{
if (elemNumber > 0)
super.create(elemNumber, 1, CvType.makeType(_depth, _channels));
}
public void fromArray(Line... a)
{
if (a == null || a.length == 0)
return;
int num = a.length;
alloc(num);
int[] buff = new int[num * _channels];
for (int i = 0; i < num; i++)
{
Line l = a[i];
buff[_channels * i + 0] = (int) l.p1.x;
buff[_channels * i + 1] = (int) l.p1.y;
buff[_channels * i + 2] = (int) l.p2.x;
buff[_channels * i + 3] = (int) l.p2.y;
}
put(0, 0, buff); // TODO: check ret val!
}
public Line[] toArray()
{
int num = (int) total();
Line[] a = new Line[num];
if (num == 0)
return a;
int[] buff = new int[num * _channels];
get(0, 0, buff); // TODO: check ret val!
for (int i = 0; i < num; i++)
a[i] = new Line(buff[i * _channels], buff[i * _channels + 1], buff[i * _channels + 2],
buff[i * _channels + 3]);
return a;
}
public void fromList(List<Line> lr)
{
Line[] ap = lr.toArray(new Line[0]);
fromArray(ap);
}
public List<Line> toList()
{
Line[] ar = toArray();
return Arrays.asList(ar);
}
}
And then use it like this:
Mat mYuv = new Mat();
Mat mRgba = new Mat();
Mat thresholdImage = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
mYuv.put(0, 0, data);
Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_YUV420sp2RGB, 4);
Imgproc.cvtColor(mRgba, thresholdImage, Imgproc.COLOR_RGB2GRAY, 4);
Imgproc.Canny(thresholdImage, thresholdImage, 80, 100, 3);
Mat lines = new Mat();
int threshold = 50;
int minLineSize = 20;
int lineGap = 20;
Imgproc.HoughLinesP(thresholdImage, lines, 1, Math.PI / 180, threshold, minLineSize, lineGap);
List<Line> convertedLines = (new MatOfLine(lines)).toList();
for (final Line line : convertedLines)
{
Imgproc.line(mRgba, line.p1, line.p2, new Scalar(255, 0, 0), 3);
}
Bitmap bmp = Bitmap.createBitmap(getFrameWidth(), getFrameHeight(), Bitmap.Config.ARGB_8888);
if (Utils.matToBitmap(mRgba, bmp))
return bmp;