Edited:
If anyone one can suggest any link or post, I will be very grateful. I am trying to find solution from two days and i can't find any.Thank you in advance.
I am trying to put one object(image) on particular location of screen Using openCv in android.
I do have Points like this "{680.0, 488.0}" which is having (x,y) coordinate,
So how can I find particular location in my screen for putting object ?
Below is my code where i am getting Point:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();
iThreshold = minTresholdSeekbar.getProgress();
//Imgproc.blur(mRgba, mRgba, new Size(5,5));
Imgproc.GaussianBlur(mRgba, mRgba, new org.opencv.core.Size(3, 3), 1, 1);
//Imgproc.medianBlur(mRgba, mRgba, 3);
if (!mIsColorSelected) return mRgba;
List<MatOfPoint> contours = mDetector.getContours();
mDetector.process(mRgba);
Log.d(TAG, "Contours count: " + contours.size());
if (contours.size() <= 0) {
return mRgba;
}
RotatedRect rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(0).toArray()));
double boundWidth = rect.size.width;
double boundHeight = rect.size.height;
int boundPos = 0;
for (int i = 1; i < contours.size(); i++) {
rect = Imgproc.minAreaRect(new MatOfPoint2f(contours.get(i).toArray()));
if (rect.size.width * rect.size.height > boundWidth * boundHeight) {
boundWidth = rect.size.width;
boundHeight = rect.size.height;
boundPos = i;
}
}
Rect boundRect = Imgproc.boundingRect(new MatOfPoint(contours.get(boundPos).toArray()));
//Core/Imgproc.rectangle( mRgba, boundRect.tl(), boundRect.br(), CONTOUR_COLOR_WHITE, 2, 8, 0 );
Log.d(TAG,
" Row start [" +
(int) boundRect.tl().y + "] row end [" +
(int) boundRect.br().y + "] Col start [" +
(int) boundRect.tl().x + "] Col end [" +
(int) boundRect.br().x + "]");
int rectHeightThresh = 0;
double a = boundRect.br().y - boundRect.tl().y;
a = a * 0.7;
a = boundRect.tl().y + a;
Log.d(TAG,
" A [" + a + "] br y - tl y = [" + (boundRect.br().y - boundRect.tl().y) + "]");
//Core.rectangle( mRgba, boundRect.tl(), boundRect.br(), CONTOUR_COLOR, 2, 8, 0 );
//Core/Imgproc.rectangle( mRgba, boundRect.tl(), new Point(boundRect.br().x, a), CONTOUR_COLOR, 2, 8, 0 );
MatOfPoint2f pointMat = new MatOfPoint2f();
Imgproc.approxPolyDP(new MatOfPoint2f(contours.get(boundPos).toArray()), pointMat, 3, true);
contours.set(boundPos, new MatOfPoint(pointMat.toArray()));
MatOfInt hull = new MatOfInt();
MatOfInt4 convexDefect = new MatOfInt4();
Imgproc.convexHull(new MatOfPoint(contours.get(boundPos).toArray()), hull);
if (hull.toArray().length < 3) return mRgba;
Imgproc.convexityDefects(new MatOfPoint(contours.get(boundPos).toArray()), hull, convexDefect);
List<MatOfPoint> hullPoints = new LinkedList<MatOfPoint>();
List<Point> listPo = new LinkedList<Point>();
for (int j = 0; j < hull.toList().size(); j++) {
listPo.add(contours.get(boundPos).toList().get(hull.toList().get(j)));
}
MatOfPoint e = new MatOfPoint();
e.fromList(listPo);
hullPoints.add(e);
List<MatOfPoint> defectPoints = new LinkedList<MatOfPoint>();
List<Point> listPoDefect = new LinkedList<Point>();
for (int j = 0; j < convexDefect.toList().size(); j = j + 4) {
Point farPoint = contours.get(boundPos).toList().get(convexDefect.toList().get(j + 2));
Integer depth = convexDefect.toList().get(j + 3);
if (depth > iThreshold && farPoint.y < a) {
listPoDefect.add(contours.get(boundPos).toList().get(convexDefect.toList().get(j + 2)));
}
Log.d(TAG, "defects [" + j + "] " + convexDefect.toList().get(j + 3));
}
MatOfPoint e2 = new MatOfPoint();
e2.fromList(listPo);
defectPoints.add(e2);
Log.d(TAG, "hull: " + hull.toList());
Log.d(TAG, "defects: " + convexDefect.toList());
Imgproc.drawContours(mRgba, hullPoints, -1, CONTOUR_COLOR, 3);
int defectsTotal = (int) convexDefect.total();
Log.d(TAG, "Defect total " + defectsTotal);
this.numberOfFingers = listPoDefect.size();
if (this.numberOfFingers > 5) {
this.numberOfFingers = 5;
} /*else if (this.numberOfFingers == 1) {
this.numberOfFingers = 0;
}
*/
mHandler.post(mUpdateFingerCountResults);
runOnUiThread(new Runnable() {
#Override
public void run() {
ring.setVisibility(View.VISIBLE);
/*LinearLayout.LayoutParams parms = new LinearLayout.LayoutParams(10,10);
ring.setLayoutParams(parms);*/
}
});
for (Point p : listPoDefect) {
Log.e("Points", p.toString());
// Imgproc.circle(mRgba, p, 6, new Scalar(255,0,255));
}
return mRgba;
}
Below is the method which i have used to save image and display. Now i need to put ring on one of captured hand fingers.
private void saveImage() {
if (MainActivity.listPoDefect.size() >= 5) {
mIsColorSelected = false;
if (listPoDefect.size() != 0) {
for (Point p :listPoDefect) {
Log.d(TAG, "before sorting X =" + String.valueOf(p.x) + " Y = " + String.valueOf(p.y));
}
Collections.sort(listPoDefect, new Comparator<Point>() {
public int compare(Point o1, Point o2) {
return Double.compare(o1.x, o2.x);
}
});
Log.d(TAG, "After Sorting ");
for (Point p : listPoDefect) {
Log.d(TAG, "after sorting X =" + String.valueOf(p.x) + " Y = " + String.valueOf(p.y));
}
}
mIsColorSelected = false;
Bitmap bitmap5 = Bitmap.createBitmap(mRgbaWithoutLine.cols(), mRgbaWithoutLine.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mRgbaWithoutLine, bitmap5);
bitmap = bitmap5;
//Create a new image bitmap and attach a brand new canvas to it
Bitmap tempBitmap = Bitmap.createBitmap(bitmap5.getWidth(), bitmap5.getHeight(), Bitmap.Config.RGB_565);
Canvas tempCanvas = new Canvas(tempBitmap);
//Draw the image bitmap into the cavas
tempCanvas.drawBitmap(bitmap5, 0, 0, null);
double scaledWidth = bitmap5.getWidth();
double scaledHeight = bitmap5.getHeight();
double xScaleFactor = scaledWidth / bitmap5.getWidth();
double yScaleFactor = scaledHeight / bitmap5.getHeight();
Paint myRectPaint = new Paint();
myRectPaint.setStyle(Paint.Style.STROKE);
myRectPaint.setColor(Color.RED);
myRectPaint.setStrokeWidth(5);
myRectPaint.setAntiAlias(true);
//this is zeroth position manipulation
double differenceX= listPoDefect.get(2).x-listPoDefect.get(1).x;
double differenceY= listPoDefect.get(2).y-listPoDefect.get(1).y;
double zeroPostionX=listPoDefect.get(1).x-differenceX;
double zeroPostionY=listPoDefect.get(1).y-differenceY;
Point pointZeroths=listPoDefect.get(0);
Point pointNew=new Point(zeroPostionX,zeroPostionY);
listPoDefect.remove(0);
listPoDefect.add(0,pointNew);
double thirdPostionX=listPoDefect.get(2).x+differenceX;
double thirdPostionY=listPoDefect.get(2).y+differenceY;
Point thirdpointNew=new Point(thirdPostionX,thirdPostionY);
listPoDefect.remove(3);
listPoDefect.add(3,thirdpointNew);
// Point pointNewThird=new Point(pointthird.x+differenc,pointthird.y);
// HomeActivity.listPoDefect.remove(3);
// HomeActivity.listPoDefect.add(3,pointNewThird);
Paint paint_text = new Paint();
paint_text.setColor(Color.WHITE);
paint_text.setStyle(Paint.Style.FILL);
paint_text.setTextSize(30);
for (int row = 0; row < 4; row++) { // draw 2 rows
Point point1 = null;
point1 = listPoDefect.get(row);
android.graphics.Point canvas_point1 = new android.graphics.Point((int) ((point1.x * xScaleFactor)), (int) ((point1.y * yScaleFactor)));
Log.d(TAG, "after sorting canvas_point1 ="+"Raw ="+row +" " + String.valueOf(canvas_point1.x) + " Y = " + String.valueOf(canvas_point1.y));
Log.d(TAG, "====================================================================================================");
if(pointFListGraphies.size()!=4)
{
pointFListGraphies.add(new PointF(canvas_point1));
}
// tempCanvas.drawRect(canvas_point1.x, canvas_point1.y, canvas_point1.x + 130, canvas_point1.y + 50, myRectPaint);
// tempCanvas.drawText(String.valueOf(row+"-"+canvas_point1.x), canvas_point1.x, canvas_point1.y, paint_text);
}
Log.d(TAG, "====================================================================================================");
for (int row = 0; row < pointFListGraphies.size(); row++) { // draw 2 rows
PointF point1 = null;
point1 = pointFListGraphies.get(row);
Log.d(TAG, "=========pointF X="+point1.x +"poninF Y =" +point1.y);
}
tempbitmap = tempBitmap;
handImage.setVisibility(View.VISIBLE);
handImage.setImageBitmap(tempbitmap);
/* Bitmap src = BitmapFactory.decodeResource(getResources(), R.drawable.ring);
tempCanvas.drawBitmap();*/
onCameraViewStopped();
//finish();
}
else {
}
}
Can anyone help me?
Thanks in advance.
OpenCV has a number of functions for writing on an image, which is usually what you are displaying on the screen.
FOr example the function to write text a particular location is
void cv::putText ( InputOutputArray img,
const String & text,
Point org,
int fontFace,
double fontScale,
Scalar color,
int thickness = 1,
int lineType = LINE_8,
bool bottomLeftOrigin = false
)
The parameters are:
Parameters
img Image.
text Text string to be drawn.
org Bottom-left corner of the text string in the image.
fontFace Font type, see cv::HersheyFonts.
fontScale Font scale factor that is multiplied by the font-specific base size.
color Text color.
thickness Thickness of the lines used to draw a text.
lineType Line type. See the line for details.
bottomLeftOrigin When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner.
You can find an overview of the drawing function here: https://docs.opencv.org/3.1.0/dc/da5/tutorial_py_drawing_functions.html
In your case, so long as your image covers the whole screen this allows you plot exactly where you want the text, or object or whatever you want too draw to appear.
Related
I try to follow up the tutorial from opencv, the difference is I'm using Android. This is the link.
I got an error out of bounds, in the line of when it tries to get the new value for new Mat
newImageData[(y * mRgba.cols() + x) * mRgba.channels() + c] = saturate(alpha * pixelValue + beta);
So here is all the code method I used.
public Bitmap brightAndContrast(Bitmap bitmap){
double alpha = 2.0;
int beta = 50;
Mat mRgba = new Mat();
Mat mResult = Mat.zeros(mRgba.size(), mRgba.type());
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Utils.bitmapToMat(bitmap, mRgba);
byte[] imageData = new byte[(int) (mRgba.total()*mRgba.channels())];
mRgba.get(0, 0, imageData);
byte[] newImageData = new byte[(int) (mResult.total()*mResult.channels())];
for (int y = 0; y < mRgba.rows(); y++) {
for (int x = 0; x < mRgba.cols(); x++) {
for (int c = 0; c < mRgba.channels(); c++) {
double pixelValue = imageData[(y * mRgba.cols() + x) * mRgba.channels() + c];
pixelValue = pixelValue < 0 ? pixelValue + 256 : pixelValue;
newImageData[(y * mRgba.cols() + x) * mRgba.channels() + c] = saturate(alpha * pixelValue + beta); // this is where the line 101
}
}
}
mResult.put(0, 0, newImageData);
Utils.matToBitmap(mResult, resultBitmap);
return resultBitmap;
}
private byte saturate(double val) {
int iVal = (int) Math.round(val);
iVal = iVal > 255 ? 255 : (iVal < 0 ? 0 : iVal);
return (byte) iVal;
}
So why does it get out of bounds?
And this is the error I get
java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
at com.wannatry.tryapps.OpenCVConverter.brightAndContrast(OpenCVConverter.java:101)
at com.wannatry.tryapps.MainActivity$15.onClick(MainActivity.java:232)
at android.view.View.performClick(View.java:5740)
at android.view.View$PerformClick.run(View.java:22947)
EDITED
this is the C++ code from the tutorial
new_image.at<Vec3b>(y,x)[c] = saturate_cast<uchar>( alpha*image.at<Vec3b>(y,x)[c] + beta );
and it translate as this code
double pixelValue = imageData[(y * image.cols() + x) * image.channels() + c]; pixelValue = pixelValue < 0 ? pixelValue + 256 : pixelValue; newImageData[(y * image.cols() + x) * image.channels() + c] = saturate(alpha * pixelValue + beta);
I am trying to use this code http://androiderstuffs.blogspot.com/2016/06/detecting-rectangle-using-opencv-java.html to detect card. But instead of putting card on plane surface, I will be holding this card in hand in-front of my Head. Problem is, its not detecting card rectangle. I am new to OpenCV. See my code below, this code will highlight all found rectangles in output image. Problem is, it never find card rectangle.
private void findRectangleOpen(Bitmap image) throws Exception {
Mat tempor = new Mat();
Mat src = new Mat();
Utils.bitmapToMat(image, tempor);
Imgproc.cvtColor(tempor, src, Imgproc.COLOR_BGR2RGB);
Mat blurred = src.clone();
Imgproc.medianBlur(src, blurred, 9);
Mat gray0 = new Mat(blurred.size(), CvType.CV_8U), gray = new Mat();
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
List<Mat> blurredChannel = new ArrayList<Mat>();
blurredChannel.add(blurred);
List<Mat> gray0Channel = new ArrayList<Mat>();
gray0Channel.add(gray0);
MatOfPoint2f approxCurve;
int maxId = -1;
for (int c = 0; c < 3; c++) {
int ch[] = {c, 0};
Core.mixChannels(blurredChannel, gray0Channel, new MatOfInt(ch));
int thresholdLevel = 1;
for (int t = 0; t < thresholdLevel; t++) {
if (t == 0) {
Imgproc.Canny(gray0, gray, 10, 20, 3, true); // true ?
Imgproc.dilate(gray, gray, new Mat(), new Point(-1, -1), 1); // 1
// ?
} else {
Imgproc.adaptiveThreshold(gray0, gray, thresholdLevel,
Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,
Imgproc.THRESH_BINARY,
(src.width() + src.height()) / 200, t);
}
Imgproc.findContours(gray, contours, new Mat(),
Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
int i = 0;
for (MatOfPoint contour : contours) {
MatOfPoint2f temp = new MatOfPoint2f(contour.toArray());
double area = Imgproc.contourArea(contour);
approxCurve = new MatOfPoint2f();
Imgproc.approxPolyDP(temp, approxCurve,
Imgproc.arcLength(temp, true) * 0.02, true);
if (approxCurve.total() == 4 && area >= 200 && area <= 40000) {
double maxCosine = 0;
List<Point> curves = approxCurve.toList();
for (int j = 2; j < 5; j++) {
double cosine = Math.abs(angle(curves.get(j % 4),
curves.get(j - 2), curves.get(j - 1)));
maxCosine = Math.max(maxCosine, cosine);
}
if (maxCosine < 0.3) {
Imgproc.drawContours(src, contours, i, new Scalar(255, 0, 0), 3);
Bitmap bmp;
bmp = Bitmap.createBitmap(src.cols(), src.rows(),
Bitmap.Config.ARGB_8888);
Utils.matToBitmap(src, bmp);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
//File origFile = getFileForSaving();
savePhoto(byteArray);
bmp.recycle();
}
}
i++;
}
}
}
}
private static double angle(org.opencv.core.Point p1, org.opencv.core.Point p2, org.opencv.core.Point p0) {
double dx1 = p1.x - p0.x;
double dy1 = p1.y - p0.y;
double dx2 = p2.x - p0.x;
double dy2 = p2.y - p0.y;
return (dx1 * dx2 + dy1 * dy2)
/ sqrt((dx1 * dx1 + dy1 * dy1) * (dx2 * dx2 + dy2 * dy2)
+ 1e-10);
}
Sample output image is:
Output of detecting rectangle
Assume that I have an image like this,
I want to draw contours around the roof and the wall. It may be achieved by color blob detection. There is a sample provided in Opencv 3.10, but its for camera view. I want it in an android imageView. Is there any way to achieve this?
Tried this code:
File imgFile = new File(Environment.getExternalStorageDirectory()+"/instahome/" + imgName);
if (imgFile.exists()) {
myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Log.d("heree",imgFile.getAbsolutePath().toString());
mRgba = new Mat(myBitmap.getHeight(), myBitmap.getWidth(), CvType.CV_8UC4);
ivw.setImageBitmap(myBitmap);
try {
detectEdges(myBitmap);
// contours(myBitmap);
}catch (Exception e)
{
Log.d("Error!!!", e.toString());
}
}
ivw.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int cols = mRgba.cols();
int rows = mRgba.rows();
int xOffset = (ivw.getWidth() - cols) / 2;
int yOffset = (ivw.getHeight() - rows) / 2;
int x = (int)event.getX() - xOffset;
int y = (int)event.getY() - yOffset;
Log.d(TAG, "Touch image coordinates: (" + x + ", " + y + ")");
if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;
Rect touchedRect = new Rect();
touchedRect.x = (x>4) ? x-4 : 0;
touchedRect.y = (y>4) ? y-4 : 0;
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
Mat touchedRegionRgba = mRgba.submat(touchedRect);
Mat touchedRegionHsv = new Mat();
Imgproc.cvtColor(touchedRegionRgba, touchedRegionHsv, Imgproc.COLOR_RGB2HSV_FULL);
// Calculate average color of touched region
mBlobColorHsv = Core.sumElems(touchedRegionHsv);
int pointCount = touchedRect.width*touchedRect.height;
for (int i = 0; i < mBlobColorHsv.val.length; i++)
mBlobColorHsv.val[i] /= pointCount;
mBlobColorRgba = converScalarHsv2Rgba(mBlobColorHsv);
Log.d(TAG, "Touched rgba color: (" + mBlobColorRgba.val[0] + ", " + mBlobColorRgba.val[1] +
", " + mBlobColorRgba.val[2] + ", " + mBlobColorRgba.val[3] + ")");
mDetector.setHsvColor(mBlobColorHsv);
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE);
mIsColorSelected = true;
if (mIsColorSelected) {
mRgba= new Mat(myBitmap.getHeight(), myBitmap.getWidth(), CvType.CV_8UC4);
mDetector.process(mRgba);
List<MatOfPoint> contours = mDetector.getContours();
Log.e(TAG, "Contours count: " + contours.size());
Imgproc.drawContours(mRgba, contours, -1, CONTOUR_COLOR);
Mat colorLabel = mRgba.submat(4, 68, 4, 68);
colorLabel.setTo(mBlobColorRgba);
Mat spectrumLabel = mRgba.submat(4, 4 + mSpectrum.rows(), 70, 70 + mSpectrum.cols());
mSpectrum.copyTo(spectrumLabel);
Bitmap newBitmap=Bitmap.createBitmap(myBitmap.getWidth(),myBitmap.getHeight(),myBitmap.getConfig());
try {
Utils.matToBitmap(mRgba,newBitmap);
}catch (Exception ex)
{
Log.d("error!", ex.toString());
}
ivw.setImageBitmap(newBitmap);
}
touchedRegionRgba.release();
touchedRegionHsv.release();
return false; // don't need subsequent touch events
}
});
addListeners();
addViews();
}
Searching around 5-6 hours, but no luck, any help will be appreciated!
I have try below code using OpenCV functions cvtColor,Canny and HoughLinesP but not able to get accurate result or not work in some cases.
private boolean opencvProcessCount(Uri picFileUri) {
hairCount = 0;
totalC = 0;
//Log.e(">>>>>>>>","count " + picFileUri);
try {
InputStream iStream = getContentResolver().openInputStream(picFileUri);
byte[] im = getBytes(iStream);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap image = BitmapFactory.decodeByteArray(im, 0, im.length);
Mat mYuv = new Mat();
Utils.bitmapToMat(image, mYuv);
Mat mRgba = new Mat();
Imgproc.cvtColor(mYuv, mRgba, Imgproc.COLOR_RGB2GRAY, 4);
Imgproc.Canny(mRgba, mRgba, 80, 90);
Mat lines = new Mat();
int threshold = 80;
int minLineSize = 30;
int lineGap = 100;
Imgproc.HoughLinesP(mRgba, lines, 1, Math.PI/180, threshold, minLineSize, lineGap);
for (int x = 0; x < lines.rows(); x++)
{
double[] vec = lines.get(x, 0);
double x1 = vec[0],
y1 = vec[1],
x2 = vec[2],
y2 = vec[3];
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
double dx = x1 - x2;
double dy = y1 - y2;
double dist = Math.sqrt (dx*dx + dy*dy);
totalC ++;
Log.e(">>>>>>>>","dist " + dist);
if(dist>300.d)
{
hairCount ++;
// Log.e(">>>>>>>>","count " + x);
Imgproc.line(mRgba, start, end, new Scalar(0,255, 0, 255),5);// here initimg is the original image.
}// show those lines that have length greater than 300
}
Log.e(">>>>>>>>",totalC+" out hairCount " + hairCount);
// Imgproc.
} catch (Throwable e) {
// Log.e(">>>>>>>>","count " + e.getMessage());
e.printStackTrace();
}
return false;
}
Below are sample images to count hair :
I think you will find this article interesting:
http://www.cs.ubc.ca/~lowe/papers/aij87.pdf
They take a 2D bitmap, apply canny edge detector and then regroup segments of the different edges based on how likely they belong to a same object - in this case hair (and give criterias for such regrouping).
I think you could use this to know how many objects there are on the image, and if the image contains only hair, then you'd have a count for hair.
I am working on an android app. I can detect lines using Canny and Hough transform but I don't know how to get the angles and lengths of the detected lines, can you help please? Here's the code:
public void countStraightLines(View view) {
try{
int iCannyLowerThreshold = 45;
int iCannyUpperThreshold = 75;
Mat rgba = Utils.loadResource(getApplicationContext(), res);
Bitmap bmp = Bitmap.createBitmap(rgba.width(), rgba.height(), Bitmap.Config.ARGB_8888);
Mat gray = new Mat ();
Imgproc.cvtColor(rgba, gray, Imgproc.COLOR_BGRA2GRAY, 4);
Imgproc.Canny(gray, gray, iCannyLowerThreshold, iCannyUpperThreshold);
Utils.matToBitmap(gray, bmp);
imgSource.setImageBitmap(bmp);
} catch (IOException e) {
Log.e(TAG, "ERROR Loading Mat");
e.printStackTrace();
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
Globals.pictSelected=parent.getItemAtPosition(position).toString();
res = getResources().getIdentifier(parent.getItemAtPosition(position).toString(), "drawable", this.getPackageName());
try {
Mat rgba = Utils.loadResource(getApplicationContext(), res);
Bitmap bmp = Bitmap.createBitmap(rgba.width(), rgba.height(), Bitmap.Config.ARGB_8888);
Mat gray = new Mat ();
Imgproc.cvtColor(rgba, gray, Imgproc.COLOR_BGRA2GRAY, 4);
int iCannyLowerThreshold = 45;
int iCannyUpperThreshold = 75;
int iHoughLinesThreshold = 50;
int iHoughLinesMinLineSize = 40;
int iHoughLinesGap = 20;
Imgproc.Canny(gray, gray, iCannyLowerThreshold, iCannyUpperThreshold);
Mat lines = new Mat();
Imgproc.HoughLinesP(gray, lines, 1, Math.PI/180, iHoughLinesThreshold, iHoughLinesMinLineSize, iHoughLinesGap);
int x = 0;
char s = 'N';
for (; x < Math.min(lines.cols(), 100); x++)
{
double[] vec = lines.get(0, x);
if (vec == null)
break;
double x1 = vec[0], y1 = vec[1], x2 = vec[2], y2 = vec[3];
Point start = new Point(x1, y1);
Point end = new Point(x2, y2);
Core.line(rgba, start, end, new Scalar(255, 0, 0, 255), 1);
if (x >= 40){s = 'C';}
else {s = 'S';}
}
text.setText("Line Count: " + x + " and The Picture is " + s);
Utils.matToBitmap(rgba, bmp);
imgSource.setImageBitmap(bmp);
} catch (IOException e) {
Log.e(TAG, "ERROR Loading Mat");
e.printStackTrace();
}
}
Thank you!
Well, it looks like you have a start point and an end point- the length is just ((starty-endy)^2+(startx-endx)^2)^(1/2). You can get the angle between them by using the fact that the dot product of two vectors A and B A.B=|A|*|B|*cos(alpha) where alpha is the angle between them. So alpha= arccos((A.B)/(|A|*|B|)).