CV exception in android - android

This is the exception im getting
CvException [org.opencv.core.CvException: cv::Exception: /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/imgproc/src/hough.cpp:712: error: (-5) The source image must be 8-bit, single-channel in function CvSeq* cvHoughLines2(CvArr*, void*, int, double, double, int, double, double)
mat = new Mat();
edges = new Mat();
lines = new Mat();
mRgba = new Mat(612, 816, CvType.CV_8UC1);
Utils.bitmapToMat(bitmap, mat);
Imgproc.Canny(mat, edges, 50, 90);
int threshold = 50;
int minLineSize = 20;
int lineGap = 20;
try {
Imgproc.HoughLines(mat, lines, 1, Math.PI / 180, threshold, minLineSize, lineGap);
for (int x = 0; x < lines.cols(); x++) {
double[] vec = lines.get(0, x);
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(mRgba, start, end, new Scalar(255, 0, 0), 3);
}
Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mRgba, bmp);
bitmap = bmp;
} catch (Exception e) {
e.printStackTrace();
System.out.println("e = " + e);
}

Your image in function HoughLines isn't right. You're not formatting it right before putting it into the function.
Try prepare image like this:
https://stackoverflow.com/a/7975315/5577679

Related

Android OpenCV FindRectangle algo not working properly

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

How to detect (Count) Hair from image using OpenCV?

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.

OpenCV circles color detection

I am trying to detect red circles on camera frames,i was trying to do the same as here https://solarianprogrammer.com/2015/05/08/detect-red-circles-image-using-opencv/ and here Android OpenCV Color detection, but it only detects blue circle O_o(screenshots link: https://drive.google.com/open?id=0B-pbp_K-xNkEWmxRa2tSMUZlUEE), here goes my code:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Mat lowerRed = new Mat();
Mat upperRed = new Mat();
Mat redHueImage = new Mat();
Mat green;
Mat blue;
Mat orange;
Mat rgba = inputFrame.rgba();
Core.flip(rgba, rgba, 1);
Mat HSVMat = new Mat();
Imgproc.medianBlur(rgba,rgba,3);
Imgproc.cvtColor(rgba, HSVMat, Imgproc.COLOR_BGR2HSV, 0);
Core.inRange(HSVMat,new Scalar(0,100,100),new Scalar(10,255,255),lowerRed);
Core.inRange(HSVMat,new Scalar(160,100,100),new Scalar(179,255,255),upperRed);
Core.addWeighted(lowerRed,1.0,upperRed,1.0,0.0,redHueImage);
Imgproc.GaussianBlur(redHueImage, redHueImage, new Size(9, 9), 2, 2);
double dp = 1.2d;
double minDist = 100;
int minRadius = 0;
int maxRadius = 0;
double param1 = 100, param2 = 20;
Mat circles = new Mat();
Imgproc.HoughCircles(redHueImage, circles, Imgproc.HOUGH_GRADIENT, dp, redHueImage.rows()/8, param1, param2, minRadius, maxRadius);
int numCircles = (circles.rows() == 0) ? 0 : circles.cols();
for (int i = 0; i < numCircles; i++) {
double[] circleCoordinates = circles.get(0, i);
int x = (int) circleCoordinates[0], y = (int) circleCoordinates[1];
Point center = new Point(x, y);
int radius = (int) circleCoordinates[2];
Imgproc.circle(rgba, center, radius, new Scalar(0, 255, 0), 4);
}
lowerRed.release();
upperRed.release();
HSVMat.release();
return rgba;
}

get lenghths and angles of detected straight Lines

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|)).

what should be my int x,y in my cropping detect face?

Hello Android Programmers here, kindly check my code to fill the parameters about cropping the image detected.
I don't know what should be the values to put in parameters about cropping the face detected in android using createBitmap(Bitmapsource,x,y,width,height).
How can i get some integer for the x and y to fill the parameters in Bitmap function.
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
mGray = inputFrame.gray();
if (mAbsoluteFaceSize == 0) {
int height = mGray.rows();
if (Math.round(height * mRelativeFaceSize) > 0) {
mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
}
mNativeDetector.setMinFaceSize(mAbsoluteFaceSize);
}
MatOfRect faces = new MatOfRect();
if (mDetectorType == JAVA_DETECTOR) {
if (mJavaDetector != null)
mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());
}
else if (mDetectorType == NATIVE_DETECTOR) {
if (mNativeDetector != null)
mNativeDetector.detect(mGray, faces);
}
else {
Log.e(TAG, "Detection method is not selected!");
}
Rect[] facesArray = faces.toArray();
for (int i = 0; i < facesArray.length; i++)
Core.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
//crop
//crop
viewWidth = part1.getMeasuredWidth();
viewHeight = part1.getMeasuredHeight();
//create the bitmap
bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888);
Resizebmp = Bitmap.createBitmap(bmp, x, y, viewWidth, viewHeight);
try {
Utils.matToBitmap(mRgba, bmp);
} catch(Exception e) {
Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());
bmp.recycle();
bmp = null;
}
return mRgba;
}
Correct me if I'm wrong. Do you mean that you had detected the face in a large bitmap and you want to crop the face out to a smaller bitmap?
For example, you have a 640 x 480 bitmap and you found the face inside rectangular with upper left x1, y1 and lower right x2, y2. Then it should be something like:
resizeBmp = Bitmap.createBitmap(bmp, x1, y1, x2 - x1, y2 - y1);

Categories

Resources