public void performMatch() { // create feature detectors and feature extractors FeatureDetector orbDetector = FeatureDetector.create(FeatureDetector.ORB); DescriptorExtractor orbExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB); // set the keypoints keyPointImg = new MatOfKeyPoint(); orbDetector.detect(imgGray, keyPointImg); MatOfKeyPoint keyPointTempl = new MatOfKeyPoint(); orbDetector.detect(templGray, keyPointTempl); // get the descriptions descImg = new Mat(image.size(), image.type()); orbExtractor.compute(imgGray, keyPointImg, descImg); Mat descTempl = new Mat(template.size(), template.type()); orbExtractor.compute(templGray, keyPointTempl, descTempl); // perform matching matches = new MatOfDMatch(); DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); matcher.match(descImg, descTempl, matches); Log.i("perform match result", matches.size().toString()); }
private void processFrameForMarkersDebug(VideoCapture capture) { ArrayList<MatOfPoint> components = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); // Get original image. capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); // Get gray scale image. capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME); // Get image segment to detect marker. Mat imgSegmentMat = cloneMarkerImageSegment(mGray); Mat thresholdedImgMat = new Mat(imgSegmentMat.size(), imgSegmentMat.type()); applyThresholdOnImage(imgSegmentMat, thresholdedImgMat); copyThresholdedImageToRgbImgMat(thresholdedImgMat, mRgba); Scalar contourColor = new Scalar(0, 0, 255); Scalar codesColor = new Scalar(255, 0, 0, 255); displayMarkersDebug(thresholdedImgMat, contourColor, codesColor); // displayThresholds(mRgba, codesColor, localThresholds); displayRectOnImageSegment(mRgba, false); if (components != null) components.clear(); if (hierarchy != null) hierarchy.release(); components = null; hierarchy = null; }
public static void main(String[] args) { try { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); Mat source = Imgcodecs.imread("test_image.jpg", 0); Mat destination = new Mat(source.rows(), source.cols(), source.type()); Imgproc.GaussianBlur(source, source, new Size(45, 45), 0); Imgproc.adaptiveThreshold( source, source, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 75, 10); Core.bitwise_not(source, source); // Line detection Mat img2 = null; Imgproc.cvtColor(source, img2, Imgproc.COLOR_GRAY2RGB); Mat img3 = null; Imgproc.cvtColor(source, img3, Imgproc.COLOR_GRAY2RGB); MatOfInt4 lines = new MatOfInt4(); // Imgproc.HoughLines(img, lines, rho, theta, threshold); // Write to File Imgcodecs.imwrite("gaussian.jpg", source); System.out.println("Success!"); } catch (Exception e) { System.out.println("Error has occurred: " + e.getMessage()); } }
public MarkerTracker(Mat image, Mat template) { this.image = image; this.template = template; Log.i("Marker-Tracker", "image is null?::" + (null == image)); imgGray = new Mat(image.size(), image.type()); templGray = new Mat(template.size(), template.type()); // Convert them to grayscale Imgproc.cvtColor(image, imgGray, Imgproc.COLOR_BGRA2GRAY); // Core.normalize(imgGray, imgGray, 0, 255, Core.NORM_MINMAX); // Mat grayImage02 = new Mat(image02.rows(), image02.cols(), image02.type()); Imgproc.cvtColor(template, templGray, Imgproc.COLOR_BGRA2GRAY); // Core.normalize(templGray, templGray, 0, 255, Core.NORM_MINMAX); }
public MarkerTracker(Mat image) { this.image = image; imgGray = new Mat(image.size(), image.type()); // Convert them to grayscale Imgproc.cvtColor(image, imgGray, Imgproc.COLOR_BGRA2GRAY); // Core.normalize(imgGray, imgGray, 0, 255, Core.NORM_MINMAX); }
public Mat onCameraFrame(CvCameraViewFrame inputFrame) { mRgba = inputFrame.rgba(); mGray = inputFrame.gray(); if (!detectionInProgress) { Mat image = new Mat(mGray.rows(), mGray.cols(), mGray.type()); mGray.copyTo(image); detectFaceOnFrame(image); } return mRgba; }
private void processFrameForMarkersFull(VideoCapture capture, DtouchMarker marker) { ArrayList<MatOfPoint> components = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); // Get original image. capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); // Get gray scale image. capture.retrieve(mGray, Highgui.CV_CAP_ANDROID_GREY_FRAME); // Get image segment to detect marker. markerPosition = calculateImageSegmentArea(mGray); Mat imgSegmentMat = cloneMarkerImageSegment(mGray); // apply threshold. Mat thresholdedImgMat = new Mat(imgSegmentMat.size(), imgSegmentMat.type()); applyThresholdOnImage(imgSegmentMat, thresholdedImgMat); imgSegmentMat.release(); // find markers. boolean markerFound = findMarkers(thresholdedImgMat, marker, components, hierarchy); thresholdedImgMat.release(); // Marker detected. if (markerFound) { setMarkerDetected(true); // if marker is found then copy the marker image segment. mMarkerImage = cloneMarkerImageSegment(mRgba); // display codes on the original image. // displayMarkerCodes(mRgba, markers); // display rect with indication that a marker is identified. displayRectOnImageSegment(mRgba, true); // display marker image displayMarkerImage(mMarkerImage, mRgba); } else displayRectOnImageSegment(mRgba, false); if (components != null) components.clear(); if (hierarchy != null) hierarchy.release(); components = null; hierarchy = null; }
public void run() { ArrayList<Geometry.Quad> squares; Mat image = new Mat(); Utils.bitmapToMat(source, image); Mat bwimage = new Mat(); cvtColor(image, bwimage, COLOR_RGB2GRAY); Mat blurred = new Mat(); medianBlur(image, blurred, 9); int width = blurred.width(); int height = blurred.height(); int depth = blurred.depth(); Mat gray0 = new Mat(width, height, depth); blurred.copyTo(gray0); squares = new ArrayList<Geometry.Quad>(); // find squares in every color plane of the image for (int c = 0; c < 3; c++) { Core.mixChannels( Arrays.asList(blurred), Arrays.asList(new Mat[] {gray0}), new MatOfInt(c, 0)); // try several threshold levels int thresholdLevel = 8; for (int l = 0; l < thresholdLevel; l++) { // use canny instead of 0 threshold level // canny helps catch squares with gradient shading Mat gray = new Mat(); if (l == 0) { Canny(gray0, gray, 10.0, 20.0, 3, false); Mat kernel = new Mat(11, 11, CvType.CV_8UC1, new Scalar(1)); dilate(gray, gray, kernel); } else { Mat thresh = new Mat(gray0.rows(), gray0.cols(), gray0.type()); threshold(gray0, thresh, ((double) l) / thresholdLevel * 255, 128, THRESH_BINARY_INV); cvtColor(thresh, gray, COLOR_BGR2GRAY); } // find contours and store them in a list List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); findContours(gray, contours, new Mat(), RETR_LIST, CHAIN_APPROX_SIMPLE); // test contours for (MatOfPoint contour : contours) { // approximate contour with accuracy proportional to the contour perimeter MatOfPoint2f thisContour = new MatOfPoint2f(contour.toArray()); double arclength = 0.02 * arcLength(thisContour, true); MatOfPoint2f approx = new MatOfPoint2f(); approxPolyDP(thisContour, approx, arclength, true); double area = contourArea(approx); boolean isConvex = isContourConvex(new MatOfPoint(approx.toArray())); if (approx.rows() == 4 && Math.abs(area) > SQUARE_SIZE && isConvex) { double maxCosine = 0; Point[] approxArray = approx.toArray(); for (int j = 2; j < 5; j++) { double cosine = Math.abs(angle(approxArray[j % 4], approxArray[j - 2], approxArray[j - 1])); maxCosine = Math.max(maxCosine, cosine); } if (maxCosine > THRESHOLD_COS) { squares.add(new Geometry.Quad(approxArray)); Log.d(TAG, "area = " + area); } } } } } result = new Bundle(); result.putParcelableArrayList("squares", squares); Log.d(TAG, "result created"); finish(); }
public void setImage(Mat image) { this.image = image; imgGray = new Mat(image.size(), image.type()); Imgproc.cvtColor(image, imgGray, Imgproc.COLOR_BGRA2GRAY); }
public void setTemplate(Mat template) { this.template = template; templGray = new Mat(template.size(), template.type()); Imgproc.cvtColor(template, templGray, Imgproc.COLOR_BGRA2GRAY); }
public MatOfPoint getContourOfBestMatch() { if (matches == null) return null; Mat threshold = new Mat(imgGray.size(), imgGray.type()); Imgproc.threshold(imgGray, threshold, 70, 255, Imgproc.THRESH_TOZERO); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours( threshold, contours, new Mat(), Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_NONE); // HashMap<Integer,MatOfPoint> coordinates = computeCoord(contours,) if (contours.size() == 0) return null; List<DMatch> matchList = matches.toList(); List<KeyPoint> keyPointList = keyPointImg.toList(); HashMap<Integer, Double> contourDensityMap = new HashMap<Integer, Double>(); Log.i("getContourBestMatch::", "contour size::" + contours.size()); for (int idx = 0; idx < contours.size(); idx++) { MatOfPoint2f ctr2f = new MatOfPoint2f(contours.get(idx).toArray()); // double contourarea = Imgproc.contourArea(contours.get(idx)); double contourarea = contours.get(idx).rows(); if (contourarea < 50) continue; Rect r = Imgproc.boundingRect(contours.get(idx)); double count = 0; // Log.i("contour area","contour area is::"+contourarea); for (DMatch match : matchList) { Point q = keyPointList.get(match.queryIdx).pt; if (q.x >= r.x && q.x <= (r.x + r.width) && q.y >= r.y && q.y <= (r.y + r.height)) count++; // // if(Imgproc.pointPolygonTest(ctr2f,keyPointList.get(match.queryIdx).pt,true)>0){ // if(null ==contourDensityMap.get(idx)) // contourDensityMap.put(idx,1.0); // // else{ // contourDensityMap.put(idx,((Double)contourDensityMap.get(idx))+1); // } // // } } // if(contourDensityMap.containsKey(idx)) { // // Log.i("contourPoint","idx::"+idx+"count::"+contourDensityMap.get(idx)+"contour // area::"+contourarea); // contourDensityMap.put(idx, contourDensityMap.get(idx) / contourarea); // } if (count != 0) { contourDensityMap.put(idx, count / contourarea); } } Log.i("MarkerTracker", "contour density size::" + contourDensityMap.size()); Map.Entry<Integer, Double> maxEntry = null; for (Map.Entry<Integer, Double> entry : contourDensityMap.entrySet()) { Log.i("contourDensityMap", "Entry value::" + entry.getValue()); if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) { maxEntry = entry; } } Log.i("maxEntry::", "" + (maxEntry == null ? null : maxEntry.getKey())); // return contours; return contours.get(maxEntry != null ? maxEntry.getKey() : 0); }
public Template performMatches(Map<String, Template> templates) { // create feature detectors and feature extractors FeatureDetector orbDetector = FeatureDetector.create(FeatureDetector.ORB); DescriptorExtractor orbExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB); MatOfKeyPoint keyPointImgT; Mat descImgT; // set the keypoints keyPointImgT = new MatOfKeyPoint(); orbDetector.detect(imgGray, keyPointImgT); descImgT = new Mat(image.size(), image.type()); orbExtractor.compute(imgGray, keyPointImgT, descImgT); Template best = null; matches = null; Map.Entry<String, Template> maxEntry = null; // MatOfDMatch matches = new MatOfDMatch(); for (Map.Entry<String, Template> entry : templates.entrySet()) { MatOfKeyPoint keyPointTempl = null; Mat descTempl = null; Mat tGray = null; Template t = entry.getValue(); if (null == t.getTemplGray() || null == t.getDescTempl() || null == t.getKeyPointTempl()) { // read image from stored data Mat templ = readImgFromFile(t.getTemplName()); tGray = new Mat(templ.size(), templ.type()); Imgproc.cvtColor(templ, tGray, Imgproc.COLOR_BGRA2GRAY); keyPointTempl = new MatOfKeyPoint(); orbDetector.detect(tGray, keyPointTempl); descTempl = new Mat(templ.size(), templ.type()); orbExtractor.compute(tGray, keyPointTempl, descTempl); t.setKeyPointTempl(keyPointTempl); t.setDescTempl(descTempl); } else { descTempl = t.getDescTempl(); } MatOfDMatch matchWithT = new MatOfDMatch(); DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING); // matcher.radiusMatch(descImgT, descTempl, matchWithT,200);// matcher.match(descImgT, descTempl, matchWithT); List<DMatch> matchList = matchWithT.toList(); // float min = Float.MAX_VALUE; // float max = Float.MIN_VALUE; // for(int i=0;i<matchList.size();i++){ // min = matchList.get(i).distance<min?matchList.get(i).distance:min; // max = matchList.get(i).distance>max?matchList.get(i).distance:max; // } // Log.i("min distance","min distance is::"+min+"max // distance::"+max+"size::"+matchList.size()); // Collections.sort(matchList, new Comparator<DMatch>() { // @Override // public int compare(DMatch o1, DMatch o2) { // if (o1.distance < o2.distance) // return -1; // if (o1.distance > o2.distance) // return 1; // return 0; // } // }); float ratio = -1; if (matchList.size() > 0) ratio = findMinTwoRatio(matchList); if (ratio > 0.8 || ratio == -1) continue; Log.i("match", "ratio::" + ratio); // Todo:revisit logic if (matches == null || (matchWithT.size().height > matches.size().height)) { matches = matchWithT; keyPointImg = keyPointImgT; descImg = descImgT; best = t; } } // Log.i("perform match result", matches.size().toString()); return best; }
public static void Circle(List<MatOfPoint> contours, int index) { int i = index; Mat mRGBA = new Mat(); Utils.bitmapToMat(image, mRGBA); // cyklus s podmienkou na konci do { int buff[] = new int[4]; hierarchy.get(0, i, buff); // Get contour form list Mat contour = contours.get(i); // id kont�ry int id = i; // dostaneme �a��ie id kont�ry i = buff[0]; // zis�ujeme �i m�me dostato�ne ve�k� kont�ru aby sme sa �ou v�bec zaoberali if (Imgproc.contourArea(contour) > 500) { List<Point> points = new ArrayList<Point>(); // dostaneme celkov� po�et kont�r int num = (int) contour.total(); // vytvor�me si pole o dvojn�sobnej ve�kosti samotnej kontury int temp[] = new int[num * 2]; // na��tame si kont�ru do do�asnej premennej contour.get(0, 0, temp); // konvertujeme List<Point> do MatOfPoint2f pre pou�itie fitEllipse for (int j = 0; j < num * 2; j = j + 2) { points.add(new Point(temp[j], temp[j + 1])); } MatOfPoint2f specialPointMtx = new MatOfPoint2f(points.toArray(new Point[0])); // do premennej bound uklad�me dokonal� elipsu RotatedRect bound = Imgproc.fitEllipse(specialPointMtx); // Vypo��ta sa hodnota pi double pi = Imgproc.contourArea(contour) / ((bound.size.height / 2) * (bound.size.width / 2)); // zis�ujeme toleranciu pi - zaoplenie if (Math.abs(pi - 3.14) > 0.03) { int k = buff[2]; // zis�ujeme �i existuje nejak� rodi� kont�ry if (k != -1) { Circle(contours, k); } continue; } // konvertujeme MatOfPoint2f do MatOfPoint pre funckiu fitEllipse - rozdie� je len v 32-bit // float a 32-bit int MatOfPoint NewMtx = new MatOfPoint(specialPointMtx.toArray()); // dostaneme s�radnice najmen�ieho mo�n�ho �tvorca Rect box = Imgproc.boundingRect(NewMtx); // nacita obrazok znova Mat mat_for_count = new Mat(); Utils.bitmapToMat(image, mat_for_count); // vytvori sa klon stvorca - dobry kandidat pre vyhladanie Mat candidate = ((mat_for_count).submat(box)).clone(); // napln maticu binarnou ciernou Mat mask = new Mat(box.size(), candidate.type(), new Scalar(0, 0, 0)); // naplni ciernu plochu bielimi konturami Imgproc.drawContours( mask, contours, id, new Scalar(255, 255, 255), -1, 8, hierarchy, 0, new Point(-box.x, -box.y)); // ulozi sa kandidat Mat roi = new Mat(candidate.size(), candidate.type(), new Scalar(255, 255, 255)); // ulozia sa len informacie o kandidatovi candidate.copyTo(roi, mask); double longAxis; double shortAxis; // ziska dve osy elipsy if (bound.size.height < bound.size.width) { shortAxis = bound.size.height / 2; longAxis = bound.size.width / 2; } else { shortAxis = bound.size.width / 2; longAxis = bound.size.height / 2; } // zastavi sa vyhladavanie pokial je elipsa prilis ovalna if ((longAxis / shortAxis) < 2.0) { signList.add(roi); boxList.add(box); } } // zis�uje sa �i je tam e�te �al�� kandid�t } while (i != -1); }
public static Mat rotateMat(Mat src) { Mat dst = new Mat(src.cols(), src.rows(), src.type()); Core.flip(src.t(), dst, 0); return dst; }
public Mat cutFrame( Mat image, double resdpi, int frameWidthPix, int frameHeightPix, boolean reverseImage, int frameNum, double scaleMult, boolean rescale, boolean correctrotation) { noCut = false; if (farEdge == null || farEdge.stdDev > worstEdgeStdDevAllowed) { System.out.println( "WARNING: far film edge for frame " + frameNum + " has a stdDev of " + (farEdge == null ? "null" : Double.toString(farEdge.stdDev)) + " and will not be used."); if (sprocketEdge == null || sprocketEdge.stdDev > worstEdgeStdDevAllowed) { System.out.println( "WARNING: near film edge for frame " + frameNum + " has a stdDev of " + (sprocketEdge == null ? "null" : Double.toString(sprocketEdge.stdDev)) + " and will not be used."); noCut = true; return null; } else preMapSetupUsingSprocketEdge( frameWidthPix, frameHeightPix, scaleMult, reverseImage, rescale, correctrotation); } else preMapSetupUsingFarEdge( frameWidthPix, frameHeightPix, scaleMult, reverseImage, rescale, correctrotation); outOfBounds = false; CvRaster srcraster = CvRaster.create(image.height(), image.width(), image.type()); srcraster.loadFrom(image); CvRaster dstraster = CvRaster.create(frameHeightPix, frameWidthPix, srcraster.type); int srcwidth = srcraster.cols; int srcheight = srcraster.rows; int dstwidth = dstraster.cols; int dstheight = dstraster.rows; for (int dstRow = 0; dstRow < dstheight; dstRow++) { for (int dstCol = 0; dstCol < dstwidth; dstCol++) { Point srclocation = map(dstRow, dstCol, frameWidthPix, frameHeightPix, reverseImage); if (leftmostCol > srclocation.x) leftmostCol = srclocation.x; if (rightmostCol < srclocation.x) rightmostCol = srclocation.x; if (topmostRow > srclocation.y) topmostRow = srclocation.y; if (bottommostRow < srclocation.y) bottommostRow = srclocation.y; if (srclocation.y < 0 || srclocation.y >= srcheight || srclocation.x < 0 || srclocation.x >= srcwidth) { dstraster.zero(dstRow, dstCol); outOfBounds = true; } else dstraster.set(dstRow, dstCol, srcraster.get(srclocation.y, srclocation.x)); } } frameCut = true; return dstraster.toMat(); }
public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // Mat mat = Mat.eye( 3, 3, CvType.CV_8UC1 ); // System.out.println( "mat = " + mat.dump() ); Sample n = new Sample(); // n.templateMatching(); // put text in image // Mat data= Highgui.imread("images/erosion.jpg"); // Core.putText(data, "Sample", new Point(50,80), Core.FONT_HERSHEY_SIMPLEX, 1, new // Scalar(0,0,0),2); // // Highgui.imwrite("images/erosion2.jpg", data); // getting dct of an image String path = "images/croppedfeature/go (20).jpg"; path = "images/wordseg/img1.png"; Mat image = Highgui.imread(path, Highgui.IMREAD_GRAYSCALE); ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.threshold(image, image, 0, 255, Imgproc.THRESH_OTSU); Imgproc.threshold(image, image, 220, 128, Imgproc.THRESH_BINARY_INV); Mat newImg = new Mat(45, 100, image.type()); newImg.setTo(new Scalar(0)); n.copyMat(image, newImg); int vgap = 25; int hgap = 45 / 3; Moments m = Imgproc.moments(image, false); Mat hu = new Mat(); Imgproc.HuMoments(m, hu); System.out.println(hu.dump()); // //divide the mat into 12 parts then get the features of each part // int count=1; // for(int j=0; j<45; j+=hgap){ // for(int i=0;i<100;i+=vgap){ // Mat result = newImg.submat(j, j+hgap, i, i+vgap); // // // Moments m= Imgproc.moments(result, false); // double m01= m.get_m01(); // double m00= m.get_m00(); // double m10 = m.get_m10(); // int x= m00!=0? (int)(m10/m00):0; // int y= m00!=0? (int)(m01/m00):0; // Mat hu= new Mat(); // Imgproc.HuMoments(m, hu); // System.out.println(hu.dump()); // System.out.println(count+" :"+x+" and "+y); // Imgproc.threshold(result, result, 0,254, Imgproc.THRESH_BINARY_INV); // Highgui.imwrite("images/submat/"+count+".jpg", result); // count++; // // } // } // // for(int i=vgap;i<100;i+=vgap){ // Point pt1= new Point(i, 0); // Point pt2= new Point(i, 99); // Core.line(newImg, pt1, pt2, new Scalar(0,0,0)); // } // for(int i=hgap;i<45;i+=hgap){ // Point pt1= new Point(0, i); // Point pt2= new Point(99, i); // Core.line(newImg, pt1, pt2, new Scalar(0,0,0)); // } // Highgui.imwrite("images/submat/copyto.jpg", newImg); }
/** * Determines which pieces are kings * * @param in Mat image of board */ public void determineKings(Mat in) { int playSquares = 32; Mat dst = new Mat(in.rows(), in.cols(), in.type()); in.copyTo(dst); Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2GRAY); // change to single color Mat canny = new Mat(); Imgproc.Canny(dst, canny, 100, 200); // make image a canny image that is only edges; 2,4 // lower threshold values find more edges List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); // holds nested contour information Imgproc.findContours( canny, contours, hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE // draw contour image Mat mask = new Mat(); mask = Mat.zeros(dst.size(), dst.type()); Imgproc.drawContours( mask, contours, -1, new Scalar(255, 255, 255), 1, 8, hierarchy, 2, new Point()); Highgui.imwrite("contours.jpg", mask); ArrayList occupied = new ArrayList<Integer>(); for (int i = 0; i < playSquares; i++) { if (board[i] != 0) occupied.add(i); } for (int i = 0; i < contours.size(); i++) // assuming only contours are checker pieces { // determine if it should be a king // use Rect r = Imgproc.boundingRect then find height of it by r.height // Get bounding rect of contour Rect bound = Imgproc.boundingRect(contours.get(i)); if (bound.height > in.rows() / 8) { // board[(int) occupied.get(0)]++; // make it a king // occupied.remove(0); } } // or apply to each region of interest /* // keep track of starting row square int parity = 0; // 0 is even, 1 is odd, tied to row number int count = 0; // row square int rowNum = 0; // row number, starting at 0 int vsegment = in.rows() / 8; // only accounts 8 playable int hsegment = in.cols() / 12; // 8 playable, 2 capture, 2 extra int offset = hsegment * 2; // offset for playable board // For angle of camera int dx = 48; hsegment -= 8; // Go through all playable squares for (int i = 0; i < playSquares; i++) { // change offset depending on the row if (parity == 0) // playable squares start on immediate left offset = hsegment * 3 + dx; else // playable squares start on 2nd square from left offset = hsegment * 2 + dx; // find where roi should be Point p1 = new Point(offset + count * hsegment, rowNum * vsegment); // top left point of rectangle (x,y) Point p2 = new Point(offset + (count + 1) * hsegment, (rowNum + 1) * vsegment); // bottom right point of rectangle (x,y) // create rectangle that is board square Rect bound = new Rect(p1, p2); // frame only includes rectangle Mat roi = new Mat(in, bound); Imgproc.cvtColor(roi, roi, Imgproc.COLOR_BGR2GRAY); // change to single color Mat canny = new Mat(); Imgproc.Canny(roi, canny, 2, 4); // make image a canny image that is only edges; 2,4 // lower threshold values find more edges List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); // holds nested contour information Imgproc.findContours(canny, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE // Get bounding rect of contour Rect rect = Imgproc.boundingRect(contours.get(0)); if (rect.height > in.rows() / 8) { board[i]++; // make it a king } count += 2; if (count == 8) { parity = ++parity % 2; // change odd or even count = 0; rowNum++; hsegment += 1; dx -= 6; } }*/ }
/** * Appelée à chaque nouvelle prise de vue par la caméra. * * <p>Son comportement sera différent suivant ce que l'on cherche à faire : * * <ul> * <li>Si la porte n'est pas stable, on cherche alors à détecter l'événement porte stable pour * pouvoir prendre une photo. * <li>Si la porte est stable mais pas fermée, cela signifie que l'on a déjà pris une photo du * contenu du frigo et on attend que la porte soit fermée pour revenir dans l'état initial. * </ul> * * @param inputFrame Image captée par la caméra */ public Mat onCameraFrame(CvCameraViewFrame inputFrame) { Mat current = inputFrame.rgba(); if (stable && !fermee) { // Une photo a été prise // On va rechercher l'événement : le flux vidéo représente des images noires Scalar scalaireN = new Scalar(0x00, 0x00, 0x00, 0xFF); Mat noir = new Mat(current.size(), current.type(), scalaireN); // noir est une matrice noire // Comparaison avec une image noire, résultat stocké dans une matrice diffNoir Mat diffNoir = new Mat(current.size(), current.type()); Core.absdiff(current, noir, diffNoir); Double normeDiffNoir = new Double(Core.norm(diffNoir)); // Calclule de la norme de cette matrice n.add(normeDiffNoir); // Ajout de cette norme dans un conteneur compteur++; // Compteur du nombre d'images prises if (compteur > 11) { // S'il y a suffisamment d'images déjà prises, on vérifie que la porte est fermée fermee = true; int i = 0; while (fermee && i < 10) { // La porte est fermee si sur les dix dernières photos prises, la différence // entre une image noire et l'image current n'est pas trop grande. if (n.get(compteur - 1 - i) > 4500) { fermee = false; // Si cette différence est trop grande, on considère que la porte n'est pas // fermée } i++; } // Si elle n'a jamais été trop grande, la porte est effectivement fermée if (fermee) { // Remise à 0 du compteur s'il doit être réutilisé pour une nouvelle photo // De même pour le tableau n compteur = 0; n.clear(); finish(); // Retour sur l'activité principale qui attend une ouverture du frigo. } } } else if (!stable) { // Aucune photo n'a encore été prise // On va rechercher l'événement : l'image est stable if (buffer == null) { // Première image reçue, il faut créer une matrice buffer qui contiendra // l'image précédente buffer = new Mat(current.size(), current.type()); buffer = current.clone(); } else { // C'est au moins la deuxième image reçue // Comparaison entre l'image précédente et l'image courante, résultat stocké dans une // matrice diffBuffer Mat diffBuffer = new Mat(current.size(), current.type()); Core.absdiff(current, buffer, diffBuffer); Double normeDiffBuffer = new Double(Core.norm(diffBuffer)); // Calcul de la norme de cette matrice n.add(normeDiffBuffer); // Ajout de cette norme dans un conteneur compteur++; // Compteur du nombre d'images prises if (compteur > 11) { // S'il y a suffisamment d'images déjà prises, on vérifie que la porte est stable stable = true; int i = 0; while (stable && i < 10) { // On est stable si sur les dix dernières prises, la différence entre // l'image current est l'image stockée n'est pas trop grande if (n.get(compteur - 1 - i) > 4500) { stable = false; } i++; } if (stable) { Log.i(TAG, "Prise de la photo"); // Si l'image est stable, il faut vérifier tout d'abord que la porte n'est pas fermée. // (on effectue ici le même traîtement que pour une détection de porte fermée) Scalar scalaireN = new Scalar(0x00, 0x00, 0x00, 0xFF); Mat noir = new Mat(current.size(), current.type(), scalaireN); Mat diffNoir = new Mat(current.size(), current.type()); Core.absdiff(current, noir, diffNoir); Double normeDiffNoir = new Double(Core.norm(diffNoir)); if (normeDiffNoir > 4500) { // Si la porte n'est pas fermée, on va sauvegarder l'image avant de l'envoyer File pictureFileDir = getDir(); SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy-HH.mm.ss"); String date = dateFormat.format(new Date()); String photoFile = "PictureCV_" + date + ".jpg"; // Nom du fichier String filename = pictureFileDir.getPath() + File.separator + photoFile; // On doit convertir les couleurs avant de sauvegarder l'image. // La description de la fonction cvtColor explique pourquoi Imgproc.cvtColor(current, current, Imgproc.COLOR_BGR2RGB); Highgui.imwrite(filename, current); // Sauvegarde Log.i(TAG, "Photo sauvegardée"); // Remise à 0 du compteur s'il doit être réutilisé pour une nouvelle photo // De même pour le tableau n compteur = 0; n.clear(); /* //Tentative de reconnaissance d'image //On va essayer de détecter la présence d'une banane pour chaque nouvelle image //captée par le téléphone Mat Grey = inputFrame.gray(); //Image prise par la caméra MatOfRect bananas = new MatOfRect(); Size minSize = new Size(30,20); Size maxSize = new Size(150,100); Log.i(TAG, "Tentative de détection de banane"); mCascadeClassifier.detectMultiScale(Grey, bananas, 1.1, 0, 10,minSize,maxSize); if (bananas.rows()>0){ Log.i(TAG, "Nombre de bananes détectées : " + bananas.rows()); } envoiPhoto(filename, bananas.rows()); //Envoi de la photo avec les données de reconnaissance //Fin de la reconnaissance de l'image */ envoiPhoto(filename); // Envoi de la photo sans les données de reconnaissance } else { // Cas où a porte est fermée // Remise à 0 du compteur s'il doit être réutilisé pour une nouvelle photo // De même pour le tableau n compteur = 0; n.clear(); finish(); } } } buffer = current.clone(); } } return inputFrame.rgba(); }