Convert OpenCv DFT example from C++ to Android - android

I want to implement follwoing OpenCV example in a Android app:
http://docs.opencv.org/doc/tutorials/core/discrete_fourier_transform/discrete_fourier_transform.html
My code is the foll0wing:
//First convert Bitmap to Mat
Mat ImageMat = new Mat ( image.getHeight(), image.getWidth(), CvType.CV_64FC1, new Scalar(4));
Bitmap myBitmap32 = image.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(myBitmap32, ImageMat);
Imgproc.cvtColor(ImageMat, ImageMat, Imgproc.COLOR_RGB2GRAY);
Mat padded = new Mat(CvType.CV_64FC1); //expand input image to optimal size
int m = Core.getOptimalDFTSize(ImageMat.rows());
int n = Core.getOptimalDFTSize(ImageMat.cols()); // on the border add zero values
Imgproc.copyMakeBorder(ImageMat, padded, 0, m - ImageMat.rows(), 0, n - ImageMat.cols(), Imgproc.BORDER_CONSTANT);
List<Mat> planes = new ArrayList<Mat>();
planes.add(padded);
planes.add(Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC1));
Mat complexI = Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC1);
Core.merge(planes, complexI); // Add to the expanded another plane with zeros
Core.dft(complexI, complexI); // this way the result may fit in the source matrix
// compute the magnitude and switch to logarithmic scale
// => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
Core.split(complexI, planes); // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
Core.magnitude(planes.get(0), planes.get(1), planes.get(1));// planes[0] = magnitude
Mat magI = planes.get(0);
Core.add(magI, Mat.ones(padded.rows(), padded.cols(), CvType.CV_64FC1), magI); // switch to logarithmic scale
Core.log(magI, magI);
Mat crop = new Mat(magI, new Rect(0, 0, magI.cols() & -2, magI.rows() & -2));
magI = crop.clone();
// rearrange the quadrants of Fourier image so that the origin is at the image center
int cx = magI.cols()/2;
int cy = magI.rows()/2;
Rect q0Rect = new Rect (0, 0, cx, cy);
Rect q1Rect = new Rect (cx, 0, cx, cy);
Rect q2Rect = new Rect (0, cy, cx, cy);
Rect q3Rect = new Rect (cx, cy, cx, cy);
Mat q0 = new Mat(magI, q0Rect); // Top-Left - Create a ROI per quadrant
Mat q1 = new Mat(magI, q1Rect); // Top-Right
Mat q2 = new Mat(magI, q2Rect); // Bottom-Left
Mat q3 = new Mat(magI, q3Rect); // Bottom-Right
Mat tmp = new Mat(); // swap quadrants (Top-Left with Bottom-Right)
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
q2.copyTo(q1);
tmp.copyTo(q2);
Core.normalize(magI, magI, 0, 1, Core.NORM_MINMAX);
Mat realResult = new Mat();
magI.convertTo(realResult, CvType.CV_64FC1);
//Then convert the processed Mat to Bitmap
Bitmap resultBitmap = Bitmap.createBitmap(ImageMat.cols(), ImageMat.rows(),Bitmap.Config.ARGB_8888);;
Utils.matToBitmap(ImageMat, resultBitmap);
//Set member to the Result Bitmap. This member is displayed in an ImageView
mResult = resultBitmap;
(note: image is the Input Bitmap and mResult is the output bitmap that is shown in a ImageView)
I get the following error:
Error: 08-08 12:17:36.207: A/libc(1594): Fatal signal 11 (SIGSEGV) at 0x0000000a (code=1), thread 1594 (XXXX)
Is anyone able to see my error?

I copied the code and got it to work on Android. There's a few changes I've made, not sure all are necessary but here they are:
having the dst and src the same is ok in C++ but I'm not sure Java implementation is as tolerant. I tend to always create different objects for these to avoid any conflicts
The 'padded' Mat object: I've initialised with the size:
Mat padded = new Mat(new Size(n, m), CvType.CV_64FC1)
Mat complexI should be of type CV_64FC2 I think.
I set the upper bound variable for the Core.normalize call to 255
I convert the results back to a CV_8UC1 so I can display on my implementation.
Here is the code I've been using:
private Mat getDFT(Mat singleChannel) {
singleChannel.convertTo(image1, CvType.CV_64FC1);
int m = Core.getOptimalDFTSize(image1.rows());
int n = Core.getOptimalDFTSize(image1.cols()); // on the border
// add zero
// values
// Imgproc.copyMakeBorder(image1,
// padded, 0, m -
// image1.rows(), 0, n
Mat padded = new Mat(new Size(n, m), CvType.CV_64FC1); // expand input
// image to
// optimal size
Imgproc.copyMakeBorder(image1, padded, 0, m - singleChannel.rows(), 0,
n - singleChannel.cols(), Imgproc.BORDER_CONSTANT);
List<Mat> planes = new ArrayList<Mat>();
planes.add(padded);
planes.add(Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC1));
Mat complexI = Mat.zeros(padded.rows(), padded.cols(), CvType.CV_64FC2);
Mat complexI2 = Mat
.zeros(padded.rows(), padded.cols(), CvType.CV_64FC2);
Core.merge(planes, complexI); // Add to the expanded another plane with
// zeros
Core.dft(complexI, complexI2); // this way the result may fit in the
// source matrix
// compute the magnitude and switch to logarithmic scale
// => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
Core.split(complexI2, planes); // planes[0] = Re(DFT(I), planes[1] =
// Im(DFT(I))
Mat mag = new Mat(planes.get(0).size(), planes.get(0).type());
Core.magnitude(planes.get(0), planes.get(1), mag);// planes[0]
// =
// magnitude
Mat magI = mag;
Mat magI2 = new Mat(magI.size(), magI.type());
Mat magI3 = new Mat(magI.size(), magI.type());
Mat magI4 = new Mat(magI.size(), magI.type());
Mat magI5 = new Mat(magI.size(), magI.type());
Core.add(magI, Mat.ones(padded.rows(), padded.cols(), CvType.CV_64FC1),
magI2); // switch to logarithmic scale
Core.log(magI2, magI3);
Mat crop = new Mat(magI3, new Rect(0, 0, magI3.cols() & -2,
magI3.rows() & -2));
magI4 = crop.clone();
// rearrange the quadrants of Fourier image so that the origin is at the
// image center
int cx = magI4.cols() / 2;
int cy = magI4.rows() / 2;
Rect q0Rect = new Rect(0, 0, cx, cy);
Rect q1Rect = new Rect(cx, 0, cx, cy);
Rect q2Rect = new Rect(0, cy, cx, cy);
Rect q3Rect = new Rect(cx, cy, cx, cy);
Mat q0 = new Mat(magI4, q0Rect); // Top-Left - Create a ROI per quadrant
Mat q1 = new Mat(magI4, q1Rect); // Top-Right
Mat q2 = new Mat(magI4, q2Rect); // Bottom-Left
Mat q3 = new Mat(magI4, q3Rect); // Bottom-Right
Mat tmp = new Mat(); // swap quadrants (Top-Left with Bottom-Right)
q0.copyTo(tmp);
q3.copyTo(q0);
tmp.copyTo(q3);
q1.copyTo(tmp); // swap quadrant (Top-Right with Bottom-Left)
q2.copyTo(q1);
tmp.copyTo(q2);
Core.normalize(magI4, magI5, 0, 255, Core.NORM_MINMAX);
Mat realResult = new Mat(magI5.size(), CvType.CV_8UC1);
magI5.convertTo(realResult, CvType.CV_8UC1);
return realResult;
}
Here is an example of the results; the background is the original image; bottom left is the single channel version passed to the function and top right is the image returned by the function.

Related

trouble using Perspective Transformation opencv

I'm working on Android and OpenCV 3.2, I want to apply the perspective transform but I have some trouble
I referenced to this official document OpenCV (go to perspective transform example ) http://docs.opencv.org/trunk/da/d6e/tutorial_py_geometric_transformations.html
but i get a rotated image result 90° or 180°
intput img = [input img ][2] output img output image 90 ° output 2 [output image 180 °][4]
this is my code
public void prespective(Bitmap img){
Mat imgSrc = new Mat();
Bitmap bmp32 = img.copy(Bitmap.Config.ARGB_8888, true);
Utils.bitmapToMat(bmp32, imgSrc);
Mat gray = new Mat();
cvtColor( imgSrc, gray, COLOR_RGBA2GRAY ); //Convert to gray
Mat thr = new Mat();
threshold( gray, thr, 125, 255, THRESH_BINARY ); //Threshold the gray
List<MatOfPoint> contours = new LinkedList<>(); // Vector for storing contours
findContours( thr, contours,new Mat(), RETR_CCOMP, CHAIN_APPROX_SIMPLE ); // Find the contours in the image
MatOfPoint m = biggestCountousMatOfPoint(contours);
RotatedRect box = Imgproc.minAreaRect(new MatOfPoint2f(m.toArray()));
Rect destImageRect = box.boundingRect();
Mat destImage = new Mat(destImageRect.size(),imgSrc.type());
final Point[] pts = new Point[4];
box.points(pts);
Mat _src = new MatOfPoint2f(pts[0], pts[1], pts[2], pts[3]);
Mat _dst = new MatOfPoint2f(new Point(0, 0), new Point(destImage.width() - 1, 0), new Point(destImage.width() - 1, destImage.height() - 1), new Point(0, destImage.height() - 1));
Mat perspectiveTransform=Imgproc.getPerspectiveTransform(_src, _dst);
Imgproc.warpPerspective(imgSrc, destImage, perspectiveTransform, destImage.size());
if(destImage.height() > 0 && destImage.width() > 0) {
Bitmap cinBitmapRotated = Bitmap.createBitmap(destImage.width(), destImage.height(), Bitmap.Config.ARGB_8888);
if (cinBitmapRotated != null) {
Utils.matToBitmap(destImage, cinBitmapRotated);
prenom2Cin.setImageBitmap(cinBitmapRotated);
}
}
}
what's the problem in my code ?

Hough line detection in android using openCV

My mRgba object has dimensions 0X0 so it doesn't return any lines on the picture
at all.I guess it is empty. What is the problem in the code? Is there a way to show lines just on
the black background?
Here is the code
mat = new Mat();
edges = new Mat();
Size kernel = new Size(5, 5);
Mat gauss = new Mat();
Mat mRgba = new Mat(612,816, CvType.CV_8UC1);
Mat lines = new Mat(612,816, CvType.CV_8UC1);
binary_image = new Mat();
Utils.bitmapToMat(bitmap, mat);
Imgproc.GaussianBlur(mat, gauss, kernel, 10000, 10000);
Imgproc.Canny(gauss, edges, 50, 90);
Imgproc.threshold(edges, binary_image, 0, 255, Imgproc.THRESH_BINARY_INV);
int threshold = 50;
int minLineSize = 20;
int lineGap = 20;
Imgproc.HoughLinesP(binary_image, 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;
EDIT: The problem has been solved by removing GaussianBlur and threshold methods
mat = new Mat();
edges = new Mat();
Mat mRgba = new Mat(612,816, CvType.CV_8UC1);
Mat lines = new Mat();
Utils.bitmapToMat(bitmap, mat);
Imgproc.Canny(mat, edges, 50, 90);
int threshold = 50;
int minLineSize = 20;
int lineGap = 20;
Imgproc.HoughLinesP(edges, 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;
You are not specifying a size for mRgba when you are creating it, it should has the same size with the image that you are trying to find lines.
You should check lines object, to see if you are able to find lines or
not. You can understand it by checking mRgba.
This doesn't seem to be the whole code, there is no image loading here. It might be better for you to share whole code and an example image as well.

OpenCV, Java compareHist() returns same value

In openCV I want to compare two histograms. First I transform Bitmap to Mat:
Bitmap puzzleBmp = BitmapFactory.decodeFile(photoPath, options)
mat = new Mat(puzzleBmp.getHeight(), puzzleBmp.getWidth(), CvType.CV_8U, new Scalar(4));
Utils.bitmapToMat(puzzleBmp, mat);
Next I want to create histogram of this image:
Mat mRgba = new Mat();
Imgproc.cvtColor(mat, mRgba, Imgproc.COLOR_RGBA2RGB);
Imgproc.GaussianBlur(mRgba, mRgba, new Size(5, 5), 0, Imgproc.BORDER_DEFAULT);
Mat mHSV = new Mat();
Imgproc.cvtColor(mRgba, mHSV, Imgproc.COLOR_RGB2HSV_FULL);
Mat hist = new Mat();
int h_bins = 30;
int s_bins = 32;
MatOfInt mHistSize = new MatOfInt (h_bins, s_bins);
MatOfFloat mRanges = new MatOfFloat(0, 179, 0, 255);
MatOfInt mChannels = new MatOfInt(0, 1);
List<Mat> lHSV = Arrays.asList(mHSV);
Mat mask2 = new Mat();
mask2 = Mat.zeros( mRgba.rows() + 2, mRgba.cols() + 2, CvType.CV_8UC1 );
Range rowRange = new Range( 1, mask2.rows() - 1 );
Range colRange = new Range( 1, mask2.cols() - 1 );
Mat mask = new Mat();
mask = mask2.submat(rowRange, colRange);
boolean accumulate = false;
Imgproc.calcHist(lHSV, mChannels, mask, hist, mHistSize, mRanges, accumulate);
Core.normalize(hist, hist, 0, 255, Core.NORM_MINMAX, -1, new Mat());
From this part I get hist. But when I make these transformations with two different images i always get from method Imgproc.compareHist() same values, which means they are the same pictures.

Android OpenCV Color detection

Currently I'm developing an app that will detect colored circles. I'm trying to do this by following this tutorial, where guy detects red circles on image with Python. I've written the same code, just for Java.
Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(),
CvType.CV_8UC3);
Mat hsv_image = new Mat();
Utils.bitmapToMat(bitmap, mat);
Imgproc.cvtColor(mat, hsv_image, Imgproc.COLOR_BGR2HSV);
Mat lower_red_hue_range = new Mat();
Mat upper_red_hue_range = new Mat();
Core.inRange(hsv_image, new Scalar(0, 100, 100), new Scalar(10, 255, 255), lower_red_hue_range);
Core.inRange(hsv_image, new Scalar(160, 100, 100), new Scalar(179, 255, 255), upper_red_hue_range);
Utils.matToBitmap(hsv_image, bitmap);
mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
image.setImageBitmap(mutableBitmap);
Image I use is identical to one from tutorial:
This is image with applied BGR2HSV:
When I execute the code using lower red hue range, it detects the blue circle. When I use upper red hue range it gives me black bmp(doesn't detect anything). How can it be? What am I doing wrong? This is literally copy moved from python to Java. Why's the result different then?
Thanks in advance.
Your mat is of CvType.CV_8UC1 image, i.e. you are working on a grayscale image. Try with CvType.CV_8UC3
Mat mat = new Mat(bitmap.getWidth(), bitmap.getHeight(), CvType.CV_8UC3);
hsv_image should look like this:
How to select a custom range:
You may want to detect a green circle.
Well, in HSV, tipically the range is:
H in [0,360]
S,V in [0,100]
However, for CV_8UC3 images, each component H,S,V can be represented by only 256 values at most, since it's stored in 1 byte. So, in OpenCV, the ranges H,S,V for CV_8UC3 are:
H in [0,180] <- halved to fit in the range
S,V in [0,255] <- stretched to fit the range
So to switch from typical range to OpenCV range you need to:
opencv_H = typical_H / 2;
opencv_S = typical_S * 2.55;
opencv_V = typical_V * 2.55;
So, green colors are around the value of hue of 120. The hue can have a value in the interval [0,360].
However, for Mat3b HSV images, the range for H is in [0,180], i.e. is halved so it can fit in a 8 bit representation with at most 256 possible values.
So, you want the H value to be around 120 / 2 = 60, say from 50 to 70.
You also set a minimum value for S,V to 100 in order to prevent very dark (almost black) colors.
Mat green_hue_range
inRange(hsv_image, cv::Scalar(50, 100, 100), cv::Scalar(70, 255, 255), green_hue_range);
use the following code and pass color to Blob detector and then pass an image to the detector
private Scalar converScalarRgba2HSV(Scalar rgba) {
Mat pointMatHsv= new Mat();
Mat pointMatRgba = new Mat(1, 1, CvType.CV_8UC3, rgba);
Imgproc.cvtColor(pointMatRgba,pointMatHsv, Imgproc.COLOR_RGB2HSV_FULL, 4);
return new Scalar(pointMatHsv.get(0, 0));}
// Blob Detector
public class ColorBlobDetector {
// Lower and Upper bounds for range checking in HSV color space
private Scalar mLowerBound = new Scalar(0);
private Scalar mUpperBound = new Scalar(0);
// Minimum contour area in percent for contours filtering
private static double mMinContourArea = 0.1;
// Color radius for range checking in HSV color space
private Scalar mColorRadius = new Scalar(25,50,50,0);
private Mat mSpectrum = new Mat();
private List<MatOfPoint> mContours = new ArrayList<MatOfPoint>();
Mat mPyrDownMat = new Mat();
Mat mHsvMat = new Mat();
Mat mMask = new Mat();
Mat mDilatedMask = new Mat();
Mat mHierarchy = new Mat();
public void setColorRadius(Scalar radius) {
mColorRadius = radius;
}
public void setHsvColor(Scalar hsvColor) {
double minH = (hsvColor.val[0] >= mColorRadius.val[0]) ? hsvColor.val[0]-mColorRadius.val[0] : 0;
double maxH = (hsvColor.val[0]+mColorRadius.val[0] <= 255) ? hsvColor.val[0]+mColorRadius.val[0] : 255;
mLowerBound.val[0] = minH;
mUpperBound.val[0] = maxH;
mLowerBound.val[1] = hsvColor.val[1] - mColorRadius.val[1];
mUpperBound.val[1] = hsvColor.val[1] + mColorRadius.val[1];
mLowerBound.val[2] = hsvColor.val[2] - mColorRadius.val[2];
mUpperBound.val[2] = hsvColor.val[2] + mColorRadius.val[2];
mLowerBound.val[3] = 0;
mUpperBound.val[3] = 255;
Mat spectrumHsv = new Mat(1, (int)(maxH-minH), CvType.CV_8UC3);
for (int j = 0; j < maxH-minH; j++) {
byte[] tmp = {(byte)(minH+j), (byte)255, (byte)255};
spectrumHsv.put(0, j, tmp);
}
Imgproc.cvtColor(spectrumHsv, mSpectrum, Imgproc.COLOR_HSV2RGB_FULL, 4);
}
public Mat getSpectrum() {
return mSpectrum;
}
public void setMinContourArea(double area) {
mMinContourArea = area;
}
public void process(Mat rgbaImage) {
Imgproc.pyrDown(rgbaImage, mPyrDownMat);
Imgproc.pyrDown(mPyrDownMat, mPyrDownMat);
Imgproc.cvtColor(mPyrDownMat, mHsvMat, Imgproc.COLOR_RGB2HSV_FULL);
Core.inRange(mHsvMat, mLowerBound, mUpperBound, mMask);
Imgproc.dilate(mMask, mDilatedMask, new Mat());
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Imgproc.findContours(mDilatedMask, contours, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
// Find max contour area
double maxArea = 0;
Iterator<MatOfPoint> each = contours.iterator();
while (each.hasNext()) {
MatOfPoint wrapper = each.next();
double area = Imgproc.contourArea(wrapper);
if (area > maxArea)
maxArea = area;
}
// Filter contours by area and resize to fit the original image size
mContours.clear();
each = contours.iterator();
while (each.hasNext()) {
MatOfPoint contour = each.next();
if (Imgproc.contourArea(contour) > mMinContourArea*maxArea) {
Core.multiply(contour, new Scalar(4,4), contour);
mContours.add(contour);
}
}
}
public List<MatOfPoint> getContours() {
return mContours;
}}
now set detector
public void initDetector() {
mDetector = new ColorBlobDetector();
mSpectrum = new Mat();
mBlobColorRgba = new Scalar(255);
mBlobColorHsv = new Scalar(255);
SPECTRUM_SIZE = new org.opencv.core.Size(500, 64);
CONTOUR_COLOR = new Scalar(0, 255, 0, 255);
mDetector.setHsvColor(converScalarRgba2HSV(new Scalar(0,255,255,255)));
Imgproc.resize(mDetector.getSpectrum(), mSpectrum, SPECTRUM_SIZE, 0, 0, Imgproc.INTER_LINEAR_EXACT);
mIsColorSelected = true;
}
now pass an image to a detector object
Mat mRgba = new Mat(inputFrame.height(), inputFrame.width(), CvType.CV_8UC4);
mRgba = inputFrame;
mDetector.process(mRgba);
List<MatOfPoint> contours = mDetector.getContours();
Log.e(TAG, "Contours count: " + contours.size());
drawContours(mRgba, contours, -1, CONTOUR_COLOR);
return mRgba;
Happy Codeing !!!

haar cascade for eye ball in opencv android

I am working on opencv eye detection project and i have sucessfully detect rectangular region of both eyes through the help of haar cascade for boths eyes. now i want to detect the eye balls from both eyes, the problem is that i have no haar cascade for eye ball tracking. kindly help me if anyone of you have this xml and suggest other solution.
here is my code of eye detection
private Mat get_template(CascadeClassifier clasificator, Rect area,int size)
{
Mat eye = new Mat();
Mat template = new Mat();
Mat mROI = mGray.submat(area);
MatOfRect eyes = new MatOfRect();
Point iris = new Point();
Rect eye_template = new Rect();
clasificator.detectMultiScale(mROI, eyes, 1.15, 2, Objdetect.CASCADE_FIND_BIGGEST_OBJECT|Objdetect.CASCADE_SCALE_IMAGE, new Size(30,30), new Size());
Rect[] eyesArray = eyes.toArray();
for (int i = 0; i < eyesArray.length; i++)
{
Rect e = eyesArray[i];
e.x = area.x + e.x;
e.y = area.y + e.y;
Core.rectangle(mROI, e.tl(), e.br(), new Scalar(25, 50, 0, 255));
Rect eye_only_rectangle = new Rect((int)e.tl().x, (int)( e.tl().y + e.height*0.4), (int)e.width, (int)(e.height*0.6));
//reduce ROI
mROI = mGray.submat(eye_only_rectangle);
Mat vyrez = mRgba.submat(eye_only_rectangle);
Core.MinMaxLocResult mmG = Core.minMaxLoc(mROI);
//Draw pink circle on eyeball
int radius = vyrez.height()/2;
// Core.circle(vyrez, mmG.minLoc, 2, new Scalar(0, 255, 0, 1), radius);
//Core.circle(vyrez, mmG.minLoc,2, new Scalar(255, 0, 255),1);
iris.x = mmG.minLoc.x + eye_only_rectangle.x;
iris.y = mmG.minLoc.y + eye_only_rectangle.y;
eye_template = new Rect((int)iris.x-size/2,(int)iris.y-size/2 ,size,size);
//draw red rectangle around eyeball
//Core.rectangle(mRgba,eye_template.tl(),eye_template.br(),new Scalar(255, 0, 0, 255), 2);
eye = (mRgba.submat(eye_only_rectangle));
template = (mGray.submat(eye_template)).clone();
//return template;
Mat eyeball_HSV = new Mat();
Mat dest = new Mat();
//Mat eye = new Mat();
//eye = mRgba.submat(eye_only_rectangle);
List<Mat> hsv_channel = new ArrayList<Mat>();
//convert image to HSV
Imgproc.cvtColor(eye, eyeball_HSV, Imgproc.COLOR_RGB2HSV, 0);
// get HSV channel
//hsv_channel[0] is hue
//hsv_channel[1] is saturation
//hsv_channel[2] is visibility
Core.split(eyeball_HSV, hsv_channel);
try
{
hsv_channel.get(0).setTo(new Scalar(145));
Log.v(TAG, "Got the Channel!");
}
catch(Exception ex)
{
ex.printStackTrace();
Log.v(TAG, "Didn't get any channel");
}
Core.merge(hsv_channel, eyeball_HSV);
Imgproc.cvtColor(eyeball_HSV, dest, Imgproc.COLOR_HSV2RGB);
Imgproc.cvtColor(dest, eye, Imgproc.COLOR_RGB2RGBA);
}
return eye;
}`enter code here`
If you are willing to consider other solutions then haar cascades, you can use facial landmark detection code. Facial landmark packages can give the location of the eyes in the image (usually, center of the eye and left and right borders).
Examples of landmark detection packages:
STASM:
http://www.milbo.users.sonic.net/stasm/
Flandmark detector:
http://cmp.felk.cvut.cz/~uricamic/flandmark/

Categories

Resources