From 72a4f1924d87eaa02f5ebdcec56088f7ac632208 Mon Sep 17 00:00:00 2001 From: Alexander Mordvintsev Date: Mon, 30 Jul 2012 12:39:41 +0400 Subject: [PATCH 01/17] feature_homography.py: building descriptor index on target capture simple AR experiment (work in progress) --- samples/python2/feature_homography.py | 128 ++++++++++++++++---------- 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/samples/python2/feature_homography.py b/samples/python2/feature_homography.py index c8b09de4c..d553deb97 100644 --- a/samples/python2/feature_homography.py +++ b/samples/python2/feature_homography.py @@ -19,11 +19,8 @@ import numpy as np import cv2 import video import common -from operator import attrgetter - -def get_size(a): - h, w = a.shape[:2] - return w, h +from collections import namedtuple +from common import getsize FLANN_INDEX_KDTREE = 1 @@ -33,12 +30,29 @@ flann_params= dict(algorithm = FLANN_INDEX_LSH, key_size = 12, # 20 multi_probe_level = 1) #2 - MIN_MATCH_COUNT = 10 + +ar_verts = np.float32([[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0], + [0, 0, 1], [0, 1, 1], [1, 1, 1], [1, 0, 1], + [0.5, 0.5, 2]]) +ar_edges = [(0, 1), (1, 2), (2, 3), (3, 0), + (4, 5), (5, 6), (6, 7), (7, 4), + (0, 4), (1, 5), (2, 6), (3, 7), + (4, 8), (5, 8), (6, 8), (7, 8)] + + + +def draw_keypoints(vis, keypoints, color = (0, 255, 255)): + for kp in keypoints: + x, y = kp.pt + cv2.circle(vis, (int(x), int(y)), 2, color) + class App: def __init__(self, src): self.cap = video.create_capture(src) + self.frame = None + self.paused = False self.ref_frame = None self.detector = cv2.ORB( nfeatures = 1000 ) @@ -47,19 +61,18 @@ class App: cv2.namedWindow('plane') self.rect_sel = common.RectSelector('plane', self.on_rect) - self.frame = None def match_frames(self): if len(self.frame_desc) < MIN_MATCH_COUNT or len(self.frame_desc) < MIN_MATCH_COUNT: return - raw_matches = self.matcher.knnMatch(self.ref_descs, trainDescriptors = self.frame_desc, k = 2) + raw_matches = self.matcher.knnMatch(self.frame_desc, k = 2) p0, p1 = [], [] for m in raw_matches: if len(m) == 2 and m[0].distance < m[1].distance * 0.75: m = m[0] - p0.append( self.ref_points[m.queryIdx].pt ) - p1.append( self.frame_points[m.trainIdx].pt ) + p0.append( self.ref_points[m.trainIdx].pt ) # queryIdx + p1.append( self.frame_points[m.queryIdx].pt ) p0, p1 = np.float32((p0, p1)) if len(p0) < MIN_MATCH_COUNT: return @@ -72,44 +85,31 @@ class App: return p0, p1, H - def on_frame(self, frame): - if self.frame is None or not self.rect_sel.dragging: - self.frame = frame = np.fliplr(frame).copy() - self.frame_points, self.frame_desc = self.detector.detectAndCompute(self.frame, None) - if self.frame_desc is None: # detectAndCompute returns descs=None if not keypoints found - self.frame_desc = [] - else: - self.ref_frame = None + def on_frame(self, vis): + match = self.match_frames() + if match is None: + return + w, h = getsize(self.frame) + p0, p1, H = match + for (x0, y0), (x1, y1) in zip(np.int32(p0), np.int32(p1)): + cv2.line(vis, (x0+w, y0), (x1, y1), (0, 255, 0)) + x0, y0, x1, y1 = self.ref_rect + corners0 = np.float32([[x0, y0], [x1, y0], [x1, y1], [x0, y1]]) + img_corners = cv2.perspectiveTransform(corners0.reshape(1, -1, 2), H) + cv2.polylines(vis, [np.int32(img_corners)], True, (255, 255, 255), 2) - w, h = get_size(self.frame) - vis = np.zeros((h, w*2, 3), np.uint8) - vis[:h,:w] = self.frame - self.rect_sel.draw(vis) - for kp in self.frame_points: - x, y = kp.pt - cv2.circle(vis, (int(x), int(y)), 2, (0, 255, 255)) - - if self.ref_frame is not None: - vis[:h,w:] = self.ref_frame - x0, y0, x1, y1 = self.ref_rect - cv2.rectangle(vis, (x0+w, y0), (x1+w, y1), (0, 255, 0), 2) - - for kp in self.ref_points: - x, y = kp.pt - cv2.circle(vis, (int(x+w), int(y)), 2, (0, 255, 255)) - - - match = self.match_frames() - if match is not None: - p0, p1, H = match - for (x0, y0), (x1, y1) in zip(np.int32(p0), np.int32(p1)): - cv2.line(vis, (x0+w, y0), (x1, y1), (0, 255, 0)) - x0, y0, x1, y1 = self.ref_rect - corners = np.float32([[x0, y0], [x1, y0], [x1, y1], [x0, y1]]) - corners = np.int32( cv2.perspectiveTransform(corners.reshape(1, -1, 2), H) ) - cv2.polylines(vis, [corners], True, (255, 255, 255), 2) - - cv2.imshow('plane', vis) + corners3d = np.hstack([corners0, np.zeros((4, 1), np.float32)]) + fx = 0.9 + K = np.float64([[fx*w, 0, 0.5*(w-1)], + [0, fx*w, 0.5*(h-1)], + [0.0,0.0, 1.0]]) + dist_coef = np.zeros(4) + ret, rvec, tvec = cv2.solvePnP(corners3d, img_corners, K, dist_coef) + verts = ar_verts * [(x1-x0), (y1-y0), -(x1-x0)*0.3] + (x0, y0, 0) + verts = cv2.projectPoints(verts, rvec, tvec, K, dist_coef)[0].reshape(-1, 2) + for i, j in ar_edges: + (x0, y0), (x1, y1) = verts[i], verts[j] + cv2.line(vis, (int(x0), int(y0)), (int(x1), int(y1)), (255, 255, 0), 2) def on_rect(self, rect): x0, y0, x1, y1 = rect @@ -123,11 +123,39 @@ class App: descs.append(desc) self.ref_points, self.ref_descs = points, np.uint8(descs) + self.matcher.clear() + self.matcher.add([self.ref_descs]) + def run(self): while True: - ret, frame = self.cap.read() - self.on_frame(frame) + playing = not self.paused and not self.rect_sel.dragging + if playing or self.frame is None: + ret, frame = self.cap.read() + if not ret: + break + self.frame = np.fliplr(frame).copy() + self.frame_points, self.frame_desc = self.detector.detectAndCompute(self.frame, None) + if self.frame_desc is None: # detectAndCompute returns descs=None if not keypoints found + self.frame_desc = [] + + w, h = getsize(self.frame) + vis = np.zeros((h, w*2, 3), np.uint8) + vis[:h,:w] = self.frame + if self.ref_frame is not None: + vis[:h,w:] = self.ref_frame + x0, y0, x1, y1 = self.ref_rect + cv2.rectangle(vis, (x0+w, y0), (x1+w, y1), (0, 255, 0), 2) + draw_keypoints(vis[:,w:], self.ref_points) + draw_keypoints(vis, self.frame_points) + + if playing and self.ref_frame is not None: + self.on_frame(vis) + + self.rect_sel.draw(vis) + cv2.imshow('plane', vis) ch = cv2.waitKey(1) + if ch == ord(' '): + self.paused = not self.paused if ch == 27: break @@ -136,5 +164,5 @@ if __name__ == '__main__': import sys try: video_src = sys.argv[1] - except: video_src = '0' + except: video_src = 0 App(video_src).run() From b9d7c712f51e2fafbab633105df09a3a6b94d2de Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Mon, 30 Jul 2012 16:02:49 +0400 Subject: [PATCH 02/17] made countNonZero SSE code SSE2-compliant and portable --- modules/core/src/stat.cpp | 61 ++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/modules/core/src/stat.cpp b/modules/core/src/stat.cpp index 2ef29eaf5..6744b1781 100644 --- a/modules/core/src/stat.cpp +++ b/modules/core/src/stat.cpp @@ -221,39 +221,42 @@ static int countNonZero_(const T* src, int len ) return nz; } -template <> -int countNonZero_ (const uchar* src, int len) +static int countNonZero8u( const uchar* src, int len ) { - int i=0, nz = 0; - #if (defined CV_SSE4_2 && CV_SSE4_2 && (_WIN64 || __amd64__)) - if(USE_SSE4_2)//5x-6x - { - __m128i pattern = _mm_setzero_si128 (); - __m128i inv = _mm_set1_epi8((char)1); - __int64 CV_DECL_ALIGNED(16) buf[2]; - for (; i<=len-16; i+=16) - { - __m128i r0 = _mm_lddqu_si128((const __m128i*)(src+i)); - __m128i res = _mm_cmpeq_epi8(r0, pattern); - res = _mm_add_epi8(res, inv);//11111111+1=00000000, 00000000+1=00000001 - _mm_store_si128 ((__m128i*)buf, res); - - __int64 countLow = _mm_popcnt_u64(buf[0]); - nz += countLow; - - __int64 countHigh = _mm_popcnt_u64(buf[1]); - nz +=countHigh; - } - } - #endif - for( ; i < len; i++ ) - nz += src[i] != 0; + int i=0, nz = 0; +#if CV_SSE2 + if(USE_SSE2)//5x-6x + { + __m128i pattern = _mm_setzero_si128 (); + static uchar tab[256]; + static volatile bool initialized = false; + if( !initialized ) + { + // we compute inverse popcount table, + // since we pass (img[x] == 0) mask as index in the table. + for( int j = 0; j < 256; j++ ) + { + int val = 0; + for( int mask = 1; mask < 256; mask += mask ) + val += (j & mask) == 0; + tab[j] = (uchar)val; + } + initialized = true; + } + + for (; i<=len-16; i+=16) + { + __m128i r0 = _mm_loadu_si128((const __m128i*)(src+i)); + int val = _mm_movemask_epi8(_mm_cmpeq_epi8(r0, pattern)); + nz += tab[val & 255] + tab[val >> 8]; + } + } +#endif + for( ; i < len; i++ ) + nz += src[i] != 0; return nz; } -static int countNonZero8u( const uchar* src, int len ) -{ return countNonZero_(src, len); } - static int countNonZero16u( const ushort* src, int len ) { return countNonZero_(src, len); } From 62a8f6783e67aa5b59869fd38324ee72a22d4b83 Mon Sep 17 00:00:00 2001 From: Philipp Wagner Date: Mon, 30 Jul 2012 19:31:10 +0200 Subject: [PATCH 03/17] FaceRecognizer supports updating a model now. Documentation has been updated to reflect latest changes. --- modules/contrib/doc/facerec/facerec_api.rst | 69 +++++++++++++++---- .../include/opencv2/contrib/contrib.hpp | 3 + modules/contrib/src/facerec.cpp | 52 +++++++++++--- 3 files changed, 99 insertions(+), 25 deletions(-) diff --git a/modules/contrib/doc/facerec/facerec_api.rst b/modules/contrib/doc/facerec/facerec_api.rst index 018a08065..6766894bb 100644 --- a/modules/contrib/doc/facerec/facerec_api.rst +++ b/modules/contrib/doc/facerec/facerec_api.rst @@ -19,16 +19,19 @@ a unified access to all face recongition algorithms in OpenCV. :: // Trains a FaceRecognizer. virtual void train(InputArray src, InputArray labels) = 0; - + + // Updates a FaceRecognizer. + virtual void update(InputArrayOfArrays src, InputArray labels); + // Gets a prediction from a FaceRecognizer. virtual int predict(InputArray src) const = 0; - + // Predicts the label and confidence for a given sample. virtual void predict(InputArray src, int &label, double &confidence) const = 0; // Serializes this object to a given filename. virtual void save(const string& filename) const; - + // Deserializes this object from a given filename. virtual void load(const string& filename); @@ -39,6 +42,7 @@ a unified access to all face recongition algorithms in OpenCV. :: virtual void load(const FileStorage& fs) = 0; }; + Description +++++++++++ @@ -99,13 +103,6 @@ If you've set the threshold to ``0.0`` as we did above, then: is going to yield ``-1`` as predicted label, which states this face is unknown. -Adding new samples to a trained FaceRecognizer -++++++++++++++++++++++++++++++++++++++++++++++ - -Adding new images to a trained :ocv:class:`FaceRecognizer` is possible, but only if the :ocv:class:`FaceRecognizer` supports it. For the Eigenfaces and Fisherfaces method each call to :ocv:func:`FaceRecognizer::train` empties the old model and estimates a new model on the given data. This is an algorithmic necessity for these two algorithms, no way around that. Please see the tutorial Guide To Face Recognition with OpenCV for details. If you call :ocv:func:`FaceRecognizer::train` on a LBPH model, the internal model is extended with the new samples. - -Please note: A :ocv:class:`FaceRecognizer` does not store your training images (this would be very memory intense), the caller is responsible for maintaining the dataset. - Getting the name of a FaceRecognizer +++++++++++++++++++++++++++++++++++++ @@ -164,6 +161,50 @@ And finally train it on the given dataset (the face images and labels): // model->train(images, labels); +FaceRecognizer::update +---------------------- + +Updates a FaceRecognizer with given data and associated labels. + +.. ocv:function:: void FaceRecognizer::update(InputArray src, InputArray labels) + + :param src: The training images, that means the faces you want to learn. The data has to be given as a ``vector``. + + :param labels: The labels corresponding to the images have to be given either as a ``vector`` or a + +This method updates a (probably trained) :ocv:class:`FaceRecognizer`, but only if the algorithm supports it. The Local Binary Patterns Histograms (LBPH) recognizer (see :ocv:func:`createLBPHFaceRecognizer`) can be updated. For the Eigenfaces and Fisherfaces method, this is algorithmically not possible and you have to re-estimate the model with :ocv:func:`FaceRecognizer::train`. In any case, a call to train empties the existing model and learns a new model, while update does not delete any model data. + +.. code-block:: cpp + + // Create a new LBPH model (it can be updated) and use the default parameters, + // this is the most common usage of this specific FaceRecognizer: + // + Ptr model = createLBPHFaceRecognizer(); + // This is the common interface to train all of the available cv::FaceRecognizer + // implementations: + // + model->train(images, labels); + // Some containers to hold new image: + vector newImages; + vector newLabels; + // You should add some images to the containers: + // + // ... + // + // Now updating the model is as easy as calling: + model->update(newImages,newLabels); + // This will preserve the old model data and extend the existing model + // with the new features extracted from newImages! + +Calling update on an Eigenfaces model (see :ocv:func:`createEigenFaceRecognizer`), which doesn't support updating, will throw an error similar to: + +.. code-block:: none + + OpenCV Error: The function/feature is not implemented (This FaceRecognizer (FaceRecognizer.Eigenfaces) does not support updating, you have to use FaceRecognizer::train to update it.) in update, file /home/philipp/git/opencv/modules/contrib/src/facerec.cpp, line 305 + terminate called after throwing an instance of 'cv::Exception' + +Please note: The :ocv:class:`FaceRecognizer` does not store your training images, because this would be very memory intense and it's not the responsibility of te :ocv:class:`FaceRecognizer` to do so. The caller is responsible for maintaining the dataset, he want to work with. + FaceRecognizer::predict ----------------------- @@ -176,8 +217,6 @@ FaceRecognizer::predict :param label: The predicted label for the given image. :param confidence: Associated confidence (e.g. distance) for the predicted label. - - The suffix ``const`` means that prediction does not affect the internal model state, so the method can be safely called from within different threads. @@ -260,7 +299,7 @@ Notes: * Training and prediction must be done on grayscale images, use :ocv:func:`cvtColor` to convert between the color spaces. * **THE EIGENFACES METHOD MAKES THE ASSUMPTION, THAT THE TRAINING AND TEST IMAGES ARE OF EQUAL SIZE.** (caps-lock, because I got so many mails asking for this). You have to make sure your input data has the correct shape, else a meaningful exception is thrown. Use :ocv:func:`resize` to resize the images. -* A call to :ocv:func:`FaceRecognizer::train` empties the Eigenfaces model and re-estimates a model on given data. +* This model does not support updating. Model internal data: ++++++++++++++++++++ @@ -287,7 +326,7 @@ Notes: * Training and prediction must be done on grayscale images, use :ocv:func:`cvtColor` to convert between the color spaces. * **THE FISHERFACES METHOD MAKES THE ASSUMPTION, THAT THE TRAINING AND TEST IMAGES ARE OF EQUAL SIZE.** (caps-lock, because I got so many mails asking for this). You have to make sure your input data has the correct shape, else a meaningful exception is thrown. Use :ocv:func:`resize` to resize the images. -* A call to :ocv:func:`FaceRecognizer::train` empties the Fisherfaces model and re-estimates a model on given data. +* This model does not support updating. Model internal data: ++++++++++++++++++++ @@ -316,7 +355,7 @@ Notes: ++++++ * The Circular Local Binary Patterns (used in training and prediction) expect the data given as grayscale images, use :ocv:func:`cvtColor` to convert between the color spaces. -* A call to :ocv:func:`FaceRecognizer::train` extends the LBPH model with given data. +* This model supports updating. Model internal data: ++++++++++++++++++++ diff --git a/modules/contrib/include/opencv2/contrib/contrib.hpp b/modules/contrib/include/opencv2/contrib/contrib.hpp index 8800c3ea2..9f8ed9d52 100644 --- a/modules/contrib/include/opencv2/contrib/contrib.hpp +++ b/modules/contrib/include/opencv2/contrib/contrib.hpp @@ -927,6 +927,9 @@ namespace cv // Trains a FaceRecognizer. CV_WRAP virtual void train(InputArrayOfArrays src, InputArray labels) = 0; + // Updates a FaceRecognizer. + CV_WRAP virtual void update(InputArrayOfArrays src, InputArray labels); + // Gets a prediction from a FaceRecognizer. virtual int predict(InputArray src) const = 0; diff --git a/modules/contrib/src/facerec.cpp b/modules/contrib/src/facerec.cpp index 250706a86..183338a9b 100644 --- a/modules/contrib/src/facerec.cpp +++ b/modules/contrib/src/facerec.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011. Philipp Wagner . + * Copyright (c) 2011,2012. Philipp Wagner . * Released to public domain under terms of the BSD Simplified license. * * Redistribution and use in source and binary forms, with or without @@ -197,10 +197,10 @@ public: void predict(InputArray _src, int &label, double &dist) const; // See FaceRecognizer::load. - virtual void load(const FileStorage& fs); + void load(const FileStorage& fs); // See FaceRecognizer::save. - virtual void save(FileStorage& fs) const; + void save(FileStorage& fs) const; AlgorithmInfo* info() const; }; @@ -223,6 +223,12 @@ private: vector _histograms; Mat _labels; + // Computes a LBPH model with images in src and + // corresponding labels in labels, possibly preserving + // old model data. + void train(InputArrayOfArrays src, InputArray labels, bool preserveData); + + public: using FaceRecognizer::save; using FaceRecognizer::load; @@ -265,6 +271,10 @@ public: // corresponding labels in labels. void train(InputArrayOfArrays src, InputArray labels); + // Updates this LBPH model with images in src and + // corresponding labels in labels. + void update(InputArrayOfArrays src, InputArray labels); + // Predicts the label of a query image in src. int predict(InputArray src) const; @@ -290,6 +300,11 @@ public: //------------------------------------------------------------------------------ // FaceRecognizer //------------------------------------------------------------------------------ +void FaceRecognizer::update(InputArrayOfArrays, InputArray) { + string error_msg = format("This FaceRecognizer (%s) does not support updating, you have to use FaceRecognizer::train to update it.", this->name().c_str()); + CV_Error(CV_StsNotImplemented, error_msg); +} + void FaceRecognizer::save(const string& filename) const { FileStorage fs(filename, FileStorage::WRITE); if (!fs.isOpened()) @@ -727,28 +742,45 @@ void LBPH::save(FileStorage& fs) const { fs << "labels" << _labels; } -void LBPH::train(InputArrayOfArrays _src, InputArray _lbls) { - if(_src.kind() != _InputArray::STD_VECTOR_MAT && _src.kind() != _InputArray::STD_VECTOR_VECTOR) { +void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels) { + this->train(_in_src, _in_labels, false); +} + +void LBPH::update(InputArrayOfArrays _in_src, InputArray _in_labels) { + // got no data, just return + if(_in_src.total() == 0) + return; + + this->train(_in_src, _in_labels, true); +} + +void LBPH::train(InputArrayOfArrays _in_src, InputArray _in_labels, bool preserveData) { + if(_in_src.kind() != _InputArray::STD_VECTOR_MAT && _in_src.kind() != _InputArray::STD_VECTOR_VECTOR) { string error_message = "The images are expected as InputArray::STD_VECTOR_MAT (a std::vector) or _InputArray::STD_VECTOR_VECTOR (a std::vector< vector<...> >)."; CV_Error(CV_StsBadArg, error_message); } - if(_src.total() == 0) { + if(_in_src.total() == 0) { string error_message = format("Empty training data was given. You'll need more than one sample to learn a model."); CV_Error(CV_StsUnsupportedFormat, error_message); - } else if(_lbls.getMat().type() != CV_32SC1) { - string error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _lbls.type()); + } else if(_in_labels.getMat().type() != CV_32SC1) { + string error_message = format("Labels must be given as integer (CV_32SC1). Expected %d, but was %d.", CV_32SC1, _in_labels.type()); CV_Error(CV_StsUnsupportedFormat, error_message); } // get the vector of matrices vector src; - _src.getMatVector(src); + _in_src.getMatVector(src); // get the label matrix - Mat labels = _lbls.getMat(); + Mat labels = _in_labels.getMat(); // check if data is well- aligned if(labels.total() != src.size()) { string error_message = format("The number of samples (src) must equal the number of labels (labels). Was len(samples)=%d, len(labels)=%d.", src.size(), _labels.total()); CV_Error(CV_StsBadArg, error_message); } + // if this model should be trained without preserving old data, delete old model data + if(!preserveData) { + _labels.release(); + _histograms.clear(); + } // append labels to _labels matrix for(size_t labelIdx = 0; labelIdx < labels.total(); labelIdx++) { _labels.push_back(labels.at((int)labelIdx)); From 40e65b96038ebfe24d9cb3ad6fa461edf66b3fc1 Mon Sep 17 00:00:00 2001 From: Philipp Wagner Date: Mon, 30 Jul 2012 19:31:49 +0200 Subject: [PATCH 04/17] facerec_demo.py: Updated contact mail address. --- samples/python2/facerec_demo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/python2/facerec_demo.py b/samples/python2/facerec_demo.py index 74f2681f3..6fd3199d8 100644 --- a/samples/python2/facerec_demo.py +++ b/samples/python2/facerec_demo.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # Software License Agreement (BSD License) # -# Copyright (c) 2012, Philipp Wagner +# Copyright (c) 2012, Philipp Wagner . # All rights reserved. # # Redistribution and use in source and binary forms, with or without From 484e83a9b6c97ad3b235cc56ec8927cf20ed1739 Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Tue, 31 Jul 2012 12:31:23 +0400 Subject: [PATCH 05/17] minor update (pictures resize removed, emulator screen-shot downscaled) --- .../android_binary_package.rst | 2 -- .../images/emulator_canny.png | Bin 61092 -> 27606 bytes 2 files changed, 2 deletions(-) diff --git a/doc/tutorials/introduction/android_binary_package/android_binary_package.rst b/doc/tutorials/introduction/android_binary_package/android_binary_package.rst index 09a0997d0..d95a34497 100644 --- a/doc/tutorials/introduction/android_binary_package/android_binary_package.rst +++ b/doc/tutorials/introduction/android_binary_package/android_binary_package.rst @@ -93,7 +93,6 @@ You need the following to be installed: But for successful compilation of some samples the **target** platform should be set to Android 3.0 (API 11) or higher. It will not prevent them from running on Android 2.2. .. image:: images/android_sdk_and_avd_manager.png - :height: 500px :alt: Android SDK Manager :align: center @@ -330,7 +329,6 @@ Well, running samples from Eclipse is very simple: * Here is ``Tutorial 2 - Use OpenCV Camera`` sample, running on top of stock camera-preview of the emulator. .. image:: images/emulator_canny.png - :height: 600px :alt: Tutorial 1 Basic - 1. Add OpenCV - running Canny :align: center diff --git a/doc/tutorials/introduction/android_binary_package/images/emulator_canny.png b/doc/tutorials/introduction/android_binary_package/images/emulator_canny.png index b411d7b4f044779d409430ad82884a4f57f60af0..1bc0511318dabe84f61b9f48045e309ee3021322 100644 GIT binary patch literal 27606 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 From 051adcb78606effd24fdcb9842d19c568c67084e Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 30 Jul 2012 15:18:48 +0400 Subject: [PATCH 06/17] added gpu BGR<->Lab and RGB<->Luv color conversion and gammaCorrection --- modules/gpu/include/opencv2/gpu/gpu.hpp | 49 ++++---- modules/gpu/src/color.cpp | 160 +++++++++++++++++++++++- modules/gpu/test/test_color.cpp | 46 +++++++ 3 files changed, 228 insertions(+), 27 deletions(-) diff --git a/modules/gpu/include/opencv2/gpu/gpu.hpp b/modules/gpu/include/opencv2/gpu/gpu.hpp index 515a4a275..f6d869435 100644 --- a/modules/gpu/include/opencv2/gpu/gpu.hpp +++ b/modules/gpu/include/opencv2/gpu/gpu.hpp @@ -622,6 +622,9 @@ CV_EXPORTS void cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn = 0, //! channel order. CV_EXPORTS void swapChannels(GpuMat& image, const int dstOrder[4], Stream& stream = Stream::Null()); +//! Routines for correcting image color gamma +CV_EXPORTS void gammaCorrection(const GpuMat& src, GpuMat& dst, bool forward = true, Stream& stream = Stream::Null()); + //! applies fixed threshold to the image CV_EXPORTS double threshold(const GpuMat& src, GpuMat& dst, double thresh, double maxval, int type, Stream& stream = Stream::Null()); @@ -1411,7 +1414,7 @@ public: }; ////////////////////////////////// CascadeClassifier_GPU ////////////////////////////////////////// -// The cascade classifier class for object detection: supports old haar and new lbp xlm formats and nvbin for haar cascades olny. +// The cascade classifier class for object detection: supports old haar and new lbp xlm formats and nvbin for haar cascades olny. class CV_EXPORTS CascadeClassifier_GPU { public: @@ -1421,28 +1424,28 @@ public: bool empty() const; bool load(const std::string& filename); - void release(); - - /* returns number of detected objects */ - int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, double scaleFactor = 1.2, int minNeighbors = 4, Size minSize = Size()); - - bool findLargestObject; - bool visualizeInPlace; - - Size getClassifierSize() const; - -private: - struct CascadeClassifierImpl; - CascadeClassifierImpl* impl; - struct HaarCascade; - struct LbpCascade; - friend class CascadeClassifier_GPU_LBP; - -public: - int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, Size maxObjectSize, Size minSize = Size(), double scaleFactor = 1.1, int minNeighbors = 4); -}; - -////////////////////////////////// SURF ////////////////////////////////////////// + void release(); + + /* returns number of detected objects */ + int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, double scaleFactor = 1.2, int minNeighbors = 4, Size minSize = Size()); + + bool findLargestObject; + bool visualizeInPlace; + + Size getClassifierSize() const; + +private: + struct CascadeClassifierImpl; + CascadeClassifierImpl* impl; + struct HaarCascade; + struct LbpCascade; + friend class CascadeClassifier_GPU_LBP; + +public: + int detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, Size maxObjectSize, Size minSize = Size(), double scaleFactor = 1.1, int minNeighbors = 4); +}; + +////////////////////////////////// SURF ////////////////////////////////////////// class CV_EXPORTS SURF_GPU { diff --git a/modules/gpu/src/color.cpp b/modules/gpu/src/color.cpp index a47758c87..1fe8e87f4 100644 --- a/modules/gpu/src/color.cpp +++ b/modules/gpu/src/color.cpp @@ -49,6 +49,7 @@ using namespace cv::gpu; void cv::gpu::cvtColor(const GpuMat&, GpuMat&, int, int, Stream&) { throw_nogpu(); } void cv::gpu::swapChannels(GpuMat&, const int[], Stream&) { throw_nogpu(); } +void cv::gpu::gammaCorrection(const GpuMat&, GpuMat&, bool, Stream&) { throw_nogpu(); } #else /* !defined (HAVE_CUDA) */ @@ -1142,6 +1143,116 @@ namespace funcs[dcn == 4][src.channels() == 4][src.depth()](src, dst, StreamAccessor::getStream(stream)); } + + void bgr_to_lab(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) + { + #if (CUDA_VERSION < 5000) + (void)src; + (void)dst; + (void)dcn; + (void)stream; + CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + #else + CV_Assert(src.depth() == CV_8U); + CV_Assert(src.channels() == 3); + + dcn = src.channels(); + + dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn)); + + NppStreamHandler h(StreamAccessor::getStream(stream)); + + NppiSize oSizeROI; + oSizeROI.width = src.cols; + oSizeROI.height = src.rows; + + nppSafeCall( nppiBGRToLab_8u_C3R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + #endif + } + + void lab_to_bgr(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) + { + #if (CUDA_VERSION < 5000) + (void)src; + (void)dst; + (void)dcn; + (void)stream; + CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + #else + CV_Assert(src.depth() == CV_8U); + CV_Assert(src.channels() == 3); + + dcn = src.channels(); + + dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn)); + + NppStreamHandler h(StreamAccessor::getStream(stream)); + + NppiSize oSizeROI; + oSizeROI.width = src.cols; + oSizeROI.height = src.rows; + + nppSafeCall( nppiLabToBGR_8u_C3R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + #endif + } + + void rgb_to_luv(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) + { + #if (CUDA_VERSION < 5000) + (void)src; + (void)dst; + (void)dcn; + (void)stream; + CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + #else + CV_Assert(src.depth() == CV_8U); + CV_Assert(src.channels() == 3 || src.channels() == 4); + + dcn = src.channels(); + + dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn)); + + NppStreamHandler h(StreamAccessor::getStream(stream)); + + NppiSize oSizeROI; + oSizeROI.width = src.cols; + oSizeROI.height = src.rows; + + if (dcn == 3) + nppSafeCall( nppiRGBToLUV_8u_C3R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + else + nppSafeCall( nppiRGBToLUV_8u_AC4R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + #endif + } + + void luv_to_rgb(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) + { + #if (CUDA_VERSION < 5000) + (void)src; + (void)dst; + (void)dcn; + (void)stream; + CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + #else + CV_Assert(src.depth() == CV_8U); + CV_Assert(src.channels() == 3 || src.channels() == 4); + + dcn = src.channels(); + + dst.create(src.size(), CV_MAKETYPE(src.depth(), dcn)); + + NppStreamHandler h(StreamAccessor::getStream(stream)); + + NppiSize oSizeROI; + oSizeROI.width = src.cols; + oSizeROI.height = src.rows; + + if (dcn == 3) + nppSafeCall( nppiLUVToRGB_8u_C3R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + else + nppSafeCall( nppiLUVToRGB_8u_AC4R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + #endif + } } void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream& stream) @@ -1203,7 +1314,7 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream 0, // =42 0, // =43 - 0, // CV_BGR2Lab =44 + bgr_to_lab, // CV_BGR2Lab =44 0, // CV_RGB2Lab =45 0, // CV_BayerBG2BGR =46 @@ -1212,7 +1323,7 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream 0, // CV_BayerGR2BGR =49 0, // CV_BGR2Luv =50 - 0, // CV_RGB2Luv =51 + rgb_to_luv, // CV_RGB2Luv =51 bgr_to_hls, // CV_BGR2HLS =52 rgb_to_hls, // CV_RGB2HLS =53 @@ -1220,10 +1331,10 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream hsv_to_bgr, // CV_HSV2BGR =54 hsv_to_rgb, // CV_HSV2RGB =55 - 0, // CV_Lab2BGR =56 + lab_to_bgr, // CV_Lab2BGR =56 0, // CV_Lab2RGB =57 0, // CV_Luv2BGR =58 - 0, // CV_Luv2RGB =59 + luv_to_rgb, // CV_Luv2RGB =59 hls_to_bgr, // CV_HLS2BGR =60 hls_to_rgb, // CV_HLS2RGB =61 @@ -1292,4 +1403,45 @@ void cv::gpu::swapChannels(GpuMat& image, const int dstOrder[4], Stream& s) cudaSafeCall( cudaDeviceSynchronize() ); } +void cv::gpu::gammaCorrection(const GpuMat& src, GpuMat& dst, bool forward, Stream& stream) +{ +#if (CUDA_VERSION < 5000) + (void)src; + (void)dst; + (void)forward; + (void)stream; + CV_Error( CV_StsNotImplemented, "This function works only with CUDA 5.0 or higher" ); +#else + typedef NppStatus (*func_t)(const Npp8u* pSrc, int nSrcStep, Npp8u* pDst, int nDstStep, NppiSize oSizeROI); + typedef NppStatus (*func_inplace_t)(Npp8u* pSrcDst, int nSrcDstStep, NppiSize oSizeROI); + + static const func_t funcs[2][5] = + { + {0, 0, 0, nppiGammaInv_8u_C3R, nppiGammaInv_8u_AC4R}, + {0, 0, 0, nppiGammaFwd_8u_C3R, nppiGammaFwd_8u_AC4R} + }; + static const func_inplace_t funcs_inplace[2][5] = + { + {0, 0, 0, nppiGammaInv_8u_C3IR, nppiGammaInv_8u_AC4IR}, + {0, 0, 0, nppiGammaFwd_8u_C3IR, nppiGammaFwd_8u_AC4IR} + }; + + CV_Assert(src.type() == CV_8UC3 || src.type() == CV_8UC4); + + dst.create(src.size(), src.type()); + + NppStreamHandler h(StreamAccessor::getStream(stream)); + + NppiSize oSizeROI; + oSizeROI.width = src.cols; + oSizeROI.height = src.rows; + + if (dst.data == src.data) + funcs_inplace[forward][src.channels()](dst.ptr(), static_cast(src.step), oSizeROI); + else + funcs[forward][src.channels()](src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI); + +#endif +} + #endif /* !defined (HAVE_CUDA) */ diff --git a/modules/gpu/test/test_color.cpp b/modules/gpu/test/test_color.cpp index 1d3ced022..1c08d6ac6 100644 --- a/modules/gpu/test/test_color.cpp +++ b/modules/gpu/test/test_color.cpp @@ -1609,6 +1609,52 @@ TEST_P(CvtColor, RGBA2YUV4) EXPECT_MAT_NEAR(dst_gold, h_dst, 1e-5); } +TEST_P(CvtColor, BGR2Lab) +{ + if (depth != CV_8U) + return; + + try + { + cv::Mat src = readImage("stereobm/aloe-L.png"); + + cv::gpu::GpuMat dst_lab = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(loadMat(src, useRoi), dst_lab, cv::COLOR_BGR2Lab); + + cv::gpu::GpuMat dst_bgr = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(dst_lab, dst_bgr, cv::COLOR_Lab2BGR); + + EXPECT_MAT_NEAR(src, dst_bgr, 10); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(CV_StsBadFlag, e.code); + } +} + +TEST_P(CvtColor, BGR2Luv) +{ + if (depth != CV_8U) + return; + + try + { + cv::Mat src = img; + + cv::gpu::GpuMat dst_luv = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(loadMat(src, useRoi), dst_luv, cv::COLOR_RGB2Luv); + + cv::gpu::GpuMat dst_rgb = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(dst_luv, dst_rgb, cv::COLOR_Luv2RGB); + + EXPECT_MAT_NEAR(src, dst_rgb, 10); + } + catch (const cv::Exception& e) + { + ASSERT_EQ(CV_StsBadFlag, e.code); + } +} + INSTANTIATE_TEST_CASE_P(GPU_ImgProc, CvtColor, testing::Combine( ALL_DEVICES, DIFFERENT_SIZES, From 79d0dc25f4e93d5f82dd855a5e140c82449c3cff Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 30 Jul 2012 18:24:52 +0400 Subject: [PATCH 07/17] added gpu RGB<->Lab and BGR<->Luv conversions --- modules/gpu/src/color.cpp | 32 ++++++++++++++--- modules/gpu/test/main.cpp | 2 -- modules/gpu/test/precomp.hpp | 5 +++ modules/gpu/test/test_color.cpp | 62 +++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/modules/gpu/src/color.cpp b/modules/gpu/src/color.cpp index 1fe8e87f4..d3cd29aa6 100644 --- a/modules/gpu/src/color.cpp +++ b/modules/gpu/src/color.cpp @@ -1170,6 +1170,12 @@ namespace #endif } + void rgb_to_lab(const GpuMat& src, GpuMat& dst, int, Stream& stream) + { + bgr_to_rgb(src, dst, -1, stream); + bgr_to_lab(dst, dst, -1, stream); + } + void lab_to_bgr(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) { #if (CUDA_VERSION < 5000) @@ -1196,6 +1202,12 @@ namespace #endif } + void lab_to_rgb(const GpuMat& src, GpuMat& dst, int, Stream& stream) + { + lab_to_bgr(src, dst, -1, stream); + bgr_to_rgb(dst, dst, -1, stream); + } + void rgb_to_luv(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) { #if (CUDA_VERSION < 5000) @@ -1225,6 +1237,12 @@ namespace #endif } + void bgr_to_luv(const GpuMat& src, GpuMat& dst, int, Stream& stream) + { + bgr_to_rgb(src, dst, -1, stream); + rgb_to_luv(dst, dst, -1, stream); + } + void luv_to_rgb(const GpuMat& src, GpuMat& dst, int dcn, Stream& stream) { #if (CUDA_VERSION < 5000) @@ -1253,6 +1271,12 @@ namespace nppSafeCall( nppiLUVToRGB_8u_AC4R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); #endif } + + void luv_to_bgr(const GpuMat& src, GpuMat& dst, int, Stream& stream) + { + luv_to_rgb(src, dst, -1, stream); + bgr_to_rgb(dst, dst, -1, stream); + } } void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream& stream) @@ -1315,14 +1339,14 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream 0, // =43 bgr_to_lab, // CV_BGR2Lab =44 - 0, // CV_RGB2Lab =45 + rgb_to_lab, // CV_RGB2Lab =45 0, // CV_BayerBG2BGR =46 0, // CV_BayerGB2BGR =47 0, // CV_BayerRG2BGR =48 0, // CV_BayerGR2BGR =49 - 0, // CV_BGR2Luv =50 + bgr_to_luv, // CV_BGR2Luv =50 rgb_to_luv, // CV_RGB2Luv =51 bgr_to_hls, // CV_BGR2HLS =52 @@ -1332,8 +1356,8 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream hsv_to_rgb, // CV_HSV2RGB =55 lab_to_bgr, // CV_Lab2BGR =56 - 0, // CV_Lab2RGB =57 - 0, // CV_Luv2BGR =58 + lab_to_rgb, // CV_Lab2RGB =57 + luv_to_bgr, // CV_Luv2BGR =58 luv_to_rgb, // CV_Luv2RGB =59 hls_to_bgr, // CV_HLS2BGR =60 diff --git a/modules/gpu/test/main.cpp b/modules/gpu/test/main.cpp index 4d9d38014..6a8c67d79 100644 --- a/modules/gpu/test/main.cpp +++ b/modules/gpu/test/main.cpp @@ -43,8 +43,6 @@ #ifdef HAVE_CUDA -#include - using namespace std; using namespace cv; using namespace cv::gpu; diff --git a/modules/gpu/test/precomp.hpp b/modules/gpu/test/precomp.hpp index cc708b55a..afc3be855 100644 --- a/modules/gpu/test/precomp.hpp +++ b/modules/gpu/test/precomp.hpp @@ -72,4 +72,9 @@ #include "utility.hpp" #include "interpolation.hpp" +#ifdef HAVE_CUDA + #include + #include +#endif + #endif diff --git a/modules/gpu/test/test_color.cpp b/modules/gpu/test/test_color.cpp index 1c08d6ac6..996f84dab 100644 --- a/modules/gpu/test/test_color.cpp +++ b/modules/gpu/test/test_color.cpp @@ -1628,7 +1628,38 @@ TEST_P(CvtColor, BGR2Lab) } catch (const cv::Exception& e) { +#if (CUDA_VERSION < 5000) ASSERT_EQ(CV_StsBadFlag, e.code); +#else + FAIL(); +#endif + } +} + +TEST_P(CvtColor, RGB2Lab) +{ + if (depth != CV_8U) + return; + + try + { + cv::Mat src = readImage("stereobm/aloe-L.png"); + + cv::gpu::GpuMat dst_lab = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(loadMat(src, useRoi), dst_lab, cv::COLOR_RGB2Lab); + + cv::gpu::GpuMat dst_bgr = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(dst_lab, dst_bgr, cv::COLOR_Lab2RGB); + + EXPECT_MAT_NEAR(src, dst_bgr, 10); + } + catch (const cv::Exception& e) + { +#if (CUDA_VERSION < 5000) + ASSERT_EQ(CV_StsBadFlag, e.code); +#else + FAIL(); +#endif } } @@ -1641,6 +1672,33 @@ TEST_P(CvtColor, BGR2Luv) { cv::Mat src = img; + cv::gpu::GpuMat dst_luv = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(loadMat(src, useRoi), dst_luv, cv::COLOR_BGR2Luv); + + cv::gpu::GpuMat dst_rgb = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(dst_luv, dst_rgb, cv::COLOR_Luv2BGR); + + EXPECT_MAT_NEAR(src, dst_rgb, 10); + } + catch (const cv::Exception& e) + { +#if (CUDA_VERSION < 5000) + ASSERT_EQ(CV_StsBadFlag, e.code); +#else + FAIL(); +#endif + } +} + +TEST_P(CvtColor, RGB2Luv) +{ + if (depth != CV_8U) + return; + + try + { + cv::Mat src = img; + cv::gpu::GpuMat dst_luv = createMat(src.size(), src.type(), useRoi); cv::gpu::cvtColor(loadMat(src, useRoi), dst_luv, cv::COLOR_RGB2Luv); @@ -1651,7 +1709,11 @@ TEST_P(CvtColor, BGR2Luv) } catch (const cv::Exception& e) { +#if (CUDA_VERSION < 5000) ASSERT_EQ(CV_StsBadFlag, e.code); +#else + FAIL(); +#endif } } From 4f99f69a29a6c3b6c3ae8736e49b650b4dccd2cf Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Tue, 31 Jul 2012 10:32:16 +0400 Subject: [PATCH 08/17] added gpu alpha premultiplication --- modules/gpu/src/color.cpp | 82 ++++++++++++++++++++++++++++++++- modules/gpu/test/test_color.cpp | 27 +++++++++++ 2 files changed, 107 insertions(+), 2 deletions(-) diff --git a/modules/gpu/src/color.cpp b/modules/gpu/src/color.cpp index d3cd29aa6..543227aeb 100644 --- a/modules/gpu/src/color.cpp +++ b/modules/gpu/src/color.cpp @@ -1277,6 +1277,31 @@ namespace luv_to_rgb(src, dst, -1, stream); bgr_to_rgb(dst, dst, -1, stream); } + + void rgba_to_mbgra(const GpuMat& src, GpuMat& dst, int, Stream& stream) + { + #if (CUDA_VERSION < 5000) + (void)src; + (void)dst; + (void)stream; + CV_Error( CV_StsBadFlag, "Unknown/unsupported color conversion code" ); + #else + CV_Assert(src.type() == CV_8UC4 || src.type() == CV_16UC4); + + dst.create(src.size(), src.type()); + + NppStreamHandler h(StreamAccessor::getStream(stream)); + + NppiSize oSizeROI; + oSizeROI.width = src.cols; + oSizeROI.height = src.rows; + + if (src.depth() == CV_8U) + nppSafeCall( nppiAlphaPremul_8u_AC4R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + else + nppSafeCall( nppiAlphaPremul_16u_AC4R(src.ptr(), static_cast(src.step), dst.ptr(), static_cast(dst.step), oSizeROI) ); + #endif + } } void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream& stream) @@ -1396,10 +1421,63 @@ void cv::gpu::cvtColor(const GpuMat& src, GpuMat& dst, int code, int dcn, Stream 0, // CV_BayerBG2GRAY = 86 0, // CV_BayerGB2GRAY = 87 0, // CV_BayerRG2GRAY = 88 - 0 // CV_BayerGR2GRAY = 89 + 0, // CV_BayerGR2GRAY = 89 + + //YUV 4:2:0 formats family + 0, // COLOR_YUV2RGB_NV12 = 90, + 0, // COLOR_YUV2BGR_NV12 = 91, + 0, // COLOR_YUV2RGB_NV21 = 92, + 0, // COLOR_YUV2BGR_NV21 = 93, + + 0, // COLOR_YUV2RGBA_NV12 = 94, + 0, // COLOR_YUV2BGRA_NV12 = 95, + 0, // COLOR_YUV2RGBA_NV21 = 96, + 0, // COLOR_YUV2BGRA_NV21 = 97, + + 0, // COLOR_YUV2RGB_YV12 = 98, + 0, // COLOR_YUV2BGR_YV12 = 99, + 0, // COLOR_YUV2RGB_IYUV = 100, + 0, // COLOR_YUV2BGR_IYUV = 101, + + 0, // COLOR_YUV2RGBA_YV12 = 102, + 0, // COLOR_YUV2BGRA_YV12 = 103, + 0, // COLOR_YUV2RGBA_IYUV = 104, + 0, // COLOR_YUV2BGRA_IYUV = 105, + + 0, // COLOR_YUV2GRAY_420 = 106, + + //YUV 4:2:2 formats family + 0, // COLOR_YUV2RGB_UYVY = 107, + 0, // COLOR_YUV2BGR_UYVY = 108, + 0, // //COLOR_YUV2RGB_VYUY = 109, + 0, // //COLOR_YUV2BGR_VYUY = 110, + + 0, // COLOR_YUV2RGBA_UYVY = 111, + 0, // COLOR_YUV2BGRA_UYVY = 112, + 0, // //COLOR_YUV2RGBA_VYUY = 113, + 0, // //COLOR_YUV2BGRA_VYUY = 114, + + 0, // COLOR_YUV2RGB_YUY2 = 115, + 0, // COLOR_YUV2BGR_YUY2 = 116, + 0, // COLOR_YUV2RGB_YVYU = 117, + 0, // COLOR_YUV2BGR_YVYU = 118, + + 0, // COLOR_YUV2RGBA_YUY2 = 119, + 0, // COLOR_YUV2BGRA_YUY2 = 120, + 0, // COLOR_YUV2RGBA_YVYU = 121, + 0, // COLOR_YUV2BGRA_YVYU = 122, + + 0, // COLOR_YUV2GRAY_UYVY = 123, + 0, // COLOR_YUV2GRAY_YUY2 = 124, + + // alpha premultiplication + rgba_to_mbgra, // COLOR_RGBA2mRGBA = 125, + 0, // COLOR_mRGBA2RGBA = 126, + + 0, // COLOR_COLORCVT_MAX = 127 }; - CV_Assert(code < 94); + CV_Assert(code < 128); func_t func = funcs[code]; diff --git a/modules/gpu/test/test_color.cpp b/modules/gpu/test/test_color.cpp index 996f84dab..89ca1a79a 100644 --- a/modules/gpu/test/test_color.cpp +++ b/modules/gpu/test/test_color.cpp @@ -1717,6 +1717,33 @@ TEST_P(CvtColor, RGB2Luv) } } +TEST_P(CvtColor, RGBA2mRGBA) +{ + if (depth != CV_8U) + return; + + try + { + cv::Mat src = randomMat(size, CV_MAKE_TYPE(depth, 4)); + + cv::gpu::GpuMat dst = createMat(src.size(), src.type(), useRoi); + cv::gpu::cvtColor(loadMat(src, useRoi), dst, cv::COLOR_RGBA2mRGBA); + + cv::Mat dst_gold; + cv::cvtColor(src, dst_gold, cv::COLOR_RGBA2mRGBA); + + EXPECT_MAT_NEAR(dst_gold, dst, 1); + } + catch (const cv::Exception& e) + { +#if (CUDA_VERSION < 5000) + ASSERT_EQ(CV_StsBadFlag, e.code); +#else + FAIL(); +#endif + } +} + INSTANTIATE_TEST_CASE_P(GPU_ImgProc, CvtColor, testing::Combine( ALL_DEVICES, DIFFERENT_SIZES, From b43cec3301b4140f63c74ea09e061de96eae65aa Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Tue, 31 Jul 2012 10:45:40 +0400 Subject: [PATCH 09/17] added gpu::graphcut for float sources (CUDA 5.0) --- modules/gpu/src/graphcuts.cpp | 82 ++++++++++++++++++++++++++--------- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/modules/gpu/src/graphcuts.cpp b/modules/gpu/src/graphcuts.cpp index aba9ee340..0546ce3ad 100644 --- a/modules/gpu/src/graphcuts.cpp +++ b/modules/gpu/src/graphcuts.cpp @@ -71,24 +71,32 @@ namespace return pState; } - private: + private: NppiGraphcutState* pState; }; } void cv::gpu::graphcut(GpuMat& terminals, GpuMat& leftTransp, GpuMat& rightTransp, GpuMat& top, GpuMat& bottom, GpuMat& labels, GpuMat& buf, Stream& s) { +#if (CUDA_VERSION < 5000) + CV_Assert(terminals.type() == CV_32S); +#else + CV_Assert(terminals.type() == CV_32S || terminals.type() == CV_32F); +#endif + Size src_size = terminals.size(); - CV_Assert(terminals.type() == CV_32S); CV_Assert(leftTransp.size() == Size(src_size.height, src_size.width)); - CV_Assert(leftTransp.type() == CV_32S); + CV_Assert(leftTransp.type() == terminals.type()); + CV_Assert(rightTransp.size() == Size(src_size.height, src_size.width)); - CV_Assert(rightTransp.type() == CV_32S); + CV_Assert(rightTransp.type() == terminals.type()); + CV_Assert(top.size() == src_size); - CV_Assert(top.type() == CV_32S); + CV_Assert(top.type() == terminals.type()); + CV_Assert(bottom.size() == src_size); - CV_Assert(bottom.type() == CV_32S); + CV_Assert(bottom.type() == terminals.type()); labels.create(src_size, CV_8U); @@ -106,44 +114,61 @@ void cv::gpu::graphcut(GpuMat& terminals, GpuMat& leftTransp, GpuMat& rightTrans NppStreamHandler h(stream); NppiGraphcutStateHandler state(sznpp, buf.ptr(), nppiGraphcutInitAlloc); - + +#if (CUDA_VERSION < 5000) nppSafeCall( nppiGraphcut_32s8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), top.ptr(), bottom.ptr(), static_cast(terminals.step), static_cast(leftTransp.step), sznpp, labels.ptr(), static_cast(labels.step), state) ); +#else + if (terminals.type() == CV_32S) + { + nppSafeCall( nppiGraphcut_32s8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), top.ptr(), bottom.ptr(), + static_cast(terminals.step), static_cast(leftTransp.step), sznpp, labels.ptr(), static_cast(labels.step), state) ); + } + else + { + nppSafeCall( nppiGraphcut_32f8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), top.ptr(), bottom.ptr(), + static_cast(terminals.step), static_cast(leftTransp.step), sznpp, labels.ptr(), static_cast(labels.step), state) ); + } +#endif if (stream == 0) cudaSafeCall( cudaDeviceSynchronize() ); } -void cv::gpu::graphcut(GpuMat& terminals, GpuMat& leftTransp, GpuMat& rightTransp, GpuMat& top, GpuMat& topLeft, GpuMat& topRight, +void cv::gpu::graphcut(GpuMat& terminals, GpuMat& leftTransp, GpuMat& rightTransp, GpuMat& top, GpuMat& topLeft, GpuMat& topRight, GpuMat& bottom, GpuMat& bottomLeft, GpuMat& bottomRight, GpuMat& labels, GpuMat& buf, Stream& s) { +#if (CUDA_VERSION < 5000) + CV_Assert(terminals.type() == CV_32S); +#else + CV_Assert(terminals.type() == CV_32S || terminals.type() == CV_32F); +#endif + Size src_size = terminals.size(); - CV_Assert(terminals.type() == CV_32S); - CV_Assert(leftTransp.size() == Size(src_size.height, src_size.width)); - CV_Assert(leftTransp.type() == CV_32S); + CV_Assert(leftTransp.type() == terminals.type()); CV_Assert(rightTransp.size() == Size(src_size.height, src_size.width)); - CV_Assert(rightTransp.type() == CV_32S); + CV_Assert(rightTransp.type() == terminals.type()); CV_Assert(top.size() == src_size); - CV_Assert(top.type() == CV_32S); + CV_Assert(top.type() == terminals.type()); CV_Assert(topLeft.size() == src_size); - CV_Assert(topLeft.type() == CV_32S); + CV_Assert(topLeft.type() == terminals.type()); CV_Assert(topRight.size() == src_size); - CV_Assert(topRight.type() == CV_32S); + CV_Assert(topRight.type() == terminals.type()); CV_Assert(bottom.size() == src_size); - CV_Assert(bottom.type() == CV_32S); + CV_Assert(bottom.type() == terminals.type()); CV_Assert(bottomLeft.size() == src_size); - CV_Assert(bottomLeft.type() == CV_32S); + CV_Assert(bottomLeft.type() == terminals.type()); CV_Assert(bottomRight.size() == src_size); - CV_Assert(bottomRight.type() == CV_32S); + CV_Assert(bottomRight.type() == terminals.type()); labels.create(src_size, CV_8U); @@ -161,11 +186,28 @@ void cv::gpu::graphcut(GpuMat& terminals, GpuMat& leftTransp, GpuMat& rightTrans NppStreamHandler h(stream); NppiGraphcutStateHandler state(sznpp, buf.ptr(), nppiGraphcut8InitAlloc); - - nppSafeCall( nppiGraphcut8_32s8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), + +#if (CUDA_VERSION < 5000) + nppSafeCall( nppiGraphcut8_32s8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), top.ptr(), topLeft.ptr(), topRight.ptr(), bottom.ptr(), bottomLeft.ptr(), bottomRight.ptr(), static_cast(terminals.step), static_cast(leftTransp.step), sznpp, labels.ptr(), static_cast(labels.step), state) ); +#else + if (terminals.type() == CV_32S) + { + nppSafeCall( nppiGraphcut8_32s8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), + top.ptr(), topLeft.ptr(), topRight.ptr(), + bottom.ptr(), bottomLeft.ptr(), bottomRight.ptr(), + static_cast(terminals.step), static_cast(leftTransp.step), sznpp, labels.ptr(), static_cast(labels.step), state) ); + } + else + { + nppSafeCall( nppiGraphcut8_32f8u(terminals.ptr(), leftTransp.ptr(), rightTransp.ptr(), + top.ptr(), topLeft.ptr(), topRight.ptr(), + bottom.ptr(), bottomLeft.ptr(), bottomRight.ptr(), + static_cast(terminals.step), static_cast(leftTransp.step), sznpp, labels.ptr(), static_cast(labels.step), state) ); + } +#endif if (stream == 0) cudaSafeCall( cudaDeviceSynchronize() ); From 7d63f9f6807a14de8bfdcf24dc102ca47128298c Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 31 Jul 2012 11:09:34 +0400 Subject: [PATCH 10/17] Android 4.1.1 native camera fix. BufferQueue class is used instaed of Surface texture. Includes in cmake updated. --- .../camera_wrapper/CMakeLists.txt | 13 +++++-- .../camera_wrapper/camera_wrapper.cpp | 36 ++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/modules/androidcamera/camera_wrapper/CMakeLists.txt b/modules/androidcamera/camera_wrapper/CMakeLists.txt index 058a2cb6d..9398635c8 100644 --- a/modules/androidcamera/camera_wrapper/CMakeLists.txt +++ b/modules/androidcamera/camera_wrapper/CMakeLists.txt @@ -4,18 +4,27 @@ project(${the_target}) link_directories("${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib") -INCLUDE_DIRECTORIES(BEFORE +if (ANDROID_VERSION VERSION_LESS "4.1") + INCLUDE_DIRECTORIES(BEFORE ${ANDROID_SOURCE_TREE} ${ANDROID_SOURCE_TREE}/frameworks/base/include/ui ${ANDROID_SOURCE_TREE}/frameworks/base/include/surfaceflinger ${ANDROID_SOURCE_TREE}/frameworks/base/include/camera ${ANDROID_SOURCE_TREE}/frameworks/base/include/media - ${ANDROID_SOURCE_TREE}/frameworks/base/include/camera ${ANDROID_SOURCE_TREE}/frameworks/base/include ${ANDROID_SOURCE_TREE}/system/core/include ${ANDROID_SOURCE_TREE}/hardware/libhardware/include ${ANDROID_SOURCE_TREE}/frameworks/base/native/include ) +else() + INCLUDE_DIRECTORIES(BEFORE + ${ANDROID_SOURCE_TREE} + ${ANDROID_SOURCE_TREE}/frameworks/native/include + ${ANDROID_SOURCE_TREE}/frameworks/av/include + ${ANDROID_SOURCE_TREE}/system/core/include + ${ANDROID_SOURCE_TREE}/hardware/libhardware/include + ) +endif() set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) diff --git a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp index 727ae6ad7..a2209c875 100644 --- a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp +++ b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp @@ -1,4 +1,4 @@ -#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1) && !defined(ANDROID_r4_0_0) && !defined(ANDROID_r4_0_3) +#if !defined(ANDROID_r2_2_0) && !defined(ANDROID_r2_3_3) && !defined(ANDROID_r3_0_1) && !defined(ANDROID_r4_0_0) && !defined(ANDROID_r4_0_3) && !defined(ANDROID_r4_1_1) # error Building camera wrapper for your version of Android is not supported by OpenCV. You need to modify OpenCV sources in order to compile camera wrapper for your version of Android. #endif @@ -12,13 +12,18 @@ #include "camera_wrapper.h" #include "../include/camera_properties.h" -#if defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) +#if defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) //Include SurfaceTexture.h file with the SurfaceTexture class # include # define MAGIC_OPENCV_TEXTURE_ID (0x10) #else // defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) //TODO: This is either 2.2 or 2.3. Include the headers for ISurface.h access +#if defined(ANDROID_r4_1_1) +#include +#include +#else # include +#endif // defined(ANDROID_r4_1_1) #endif // defined(ANDROID_r3_0_1) || defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) #include @@ -53,6 +58,17 @@ using namespace android; +class ConsumerListenerStub: public BufferQueue::ConsumerListener +{ +public: + virtual void onFrameAvailable() + { + } + virtual void onBuffersReleased() + { + } +}; + void debugShowFPS() { static int mFrameCount = 0; @@ -260,7 +276,7 @@ public: } virtual void postData(int32_t msgType, const sp& dataPtr -#if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) +#if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) ,camera_frame_metadata_t* metadata #endif ) @@ -506,9 +522,16 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, pdstatus = camera->setPreviewTexture(surfaceTexture); if (pdstatus != 0) LOGE("initCameraConnect: failed setPreviewTexture call; camera migth not work correctly"); +#elif defined(ANDROID_r4_1_1) + sp bufferQueue = new BufferQueue(); + sp queueListener = new ConsumerListenerStub(); + bufferQueue->consumerConnect(queueListener); + pdstatus = camera->setPreviewTexture(bufferQueue); + if (pdstatus != 0) + LOGE("initCameraConnect: failed setPreviewTexture call; camera migth not work correctly"); #endif -#if !(defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)) +#if (defined(ANDROID_r2_2_0) || defined(ANDROID_r2_3_3) || defined(ANDROID_r3_0_1)) # if 1 ////ATTENTION: switching between two versions: with and without copying memory inside Android OS //// see the method CameraService::Client::copyFrameAndPostCopiedFrame and where it is used @@ -520,6 +543,7 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, camera->setPreviewCallbackFlags( CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK | CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK);//with copy #endif //!(defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3)) + LOGD("Starting preview"); status_t resStart = camera->startPreview(); if (resStart != 0) @@ -528,6 +552,10 @@ CameraHandler* CameraHandler::initCameraConnect(const CameraCallback& callback, handler->closeCameraConnect(); handler = 0; } + else + { + LOGD("Preview started successfully"); + } return handler; } From f1e3bc850b8b22daccc4277cfd2036fcebf161a6 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 31 Jul 2012 12:15:54 +0400 Subject: [PATCH 11/17] Warning fix. ifdefs for 4.1.1 added. --- modules/androidcamera/camera_wrapper/camera_wrapper.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp index a2209c875..c7a55fb39 100644 --- a/modules/androidcamera/camera_wrapper/camera_wrapper.cpp +++ b/modules/androidcamera/camera_wrapper/camera_wrapper.cpp @@ -58,6 +58,9 @@ using namespace android; +void debugShowFPS(); + +#if defined(ANDROID_r4_1_1) class ConsumerListenerStub: public BufferQueue::ConsumerListener { public: @@ -68,6 +71,7 @@ public: { } }; +#endif void debugShowFPS() { @@ -277,7 +281,7 @@ public: virtual void postData(int32_t msgType, const sp& dataPtr #if defined(ANDROID_r4_0_0) || defined(ANDROID_r4_0_3) || defined(ANDROID_r4_1_1) - ,camera_frame_metadata_t* metadata + ,camera_frame_metadata_t* #endif ) { From d0608c2cd4e1f3615e2d575196cf07b2a1a03d74 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 31 Jul 2012 12:23:48 +0400 Subject: [PATCH 12/17] Shared libraries for native Android camera updated. --- .../armeabi-v7a/libnative_camera_r2.2.0.so | Bin 43960 -> 56492 bytes .../armeabi-v7a/libnative_camera_r2.3.3.so | Bin 43968 -> 43968 bytes .../armeabi-v7a/libnative_camera_r3.0.1.so | Bin 43984 -> 43984 bytes .../armeabi-v7a/libnative_camera_r4.0.0.so | Bin 43984 -> 43984 bytes .../armeabi-v7a/libnative_camera_r4.0.3.so | Bin 43984 -> 43984 bytes .../armeabi-v7a/libnative_camera_r4.1.1.so | Bin 0 -> 45232 bytes .../lib/armeabi/libnative_camera_r2.2.0.so | Bin 43980 -> 57068 bytes .../lib/armeabi/libnative_camera_r2.3.3.so | Bin 43992 -> 43992 bytes .../lib/armeabi/libnative_camera_r3.0.1.so | Bin 44008 -> 44008 bytes .../lib/armeabi/libnative_camera_r4.0.0.so | Bin 44008 -> 44008 bytes .../lib/armeabi/libnative_camera_r4.0.3.so | Bin 44008 -> 44008 bytes .../lib/armeabi/libnative_camera_r4.1.1.so | Bin 0 -> 45616 bytes 3rdparty/lib/x86/libnative_camera_r2.3.3.so | Bin 52128 -> 52128 bytes 3rdparty/lib/x86/libnative_camera_r3.0.1.so | Bin 52144 -> 52144 bytes 3rdparty/lib/x86/libnative_camera_r4.0.3.so | Bin 52144 -> 52144 bytes 3rdparty/lib/x86/libnative_camera_r4.1.1.so | Bin 0 -> 54080 bytes 16 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 3rdparty/lib/armeabi-v7a/libnative_camera_r4.1.1.so create mode 100644 3rdparty/lib/armeabi/libnative_camera_r4.1.1.so create mode 100644 3rdparty/lib/x86/libnative_camera_r4.1.1.so diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.2.0.so index cd429b923eab1ed2b2e6f8a0c81280637cb9f58d..ba36efcdf5d80aa51079b453309d40347d7d0867 100755 GIT binary patch literal 56492 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 literal 43960 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 _tFQaVrCFZ2vgmrG8Kn0oO>*)* zl{Tk!v8BpVQ)az(q2_t3==SWK;wb!BXS2m12>^qId0r zsroJ>zc^=cM!qp8f5}Knf^C)|;1MIjpwVJFVs#YlG8VM?-~{ z;38*os@YuUtTH<*9kutEtE@F^ot0**!%^#?aZ2T#sn`T;FeICcqy-(TT%9$itjLm6 zhE;t&SeIKZRaLcR7H}^Gu9qjdA}5NNYhcA@Dcg|ZMXIdIMRml&Vz*msux?@!k=DkV zd!!A54-W&;vdXdwWg3}5U7c-hjl!VXT1^YGzrkgYCJbeMp@|4>Cc>*sTZZ{Vvy6%6 zvO=^~Zsk=Y6J}oXaya^2~Wz`Adqkvjp_EpV6oE zd2*edHpOi6&dO5u41@MFuh3et7$a+bxwQ-ft+r+@%*OA!n^sm;TW6K)%B-!a!Nx+i zMWrrQiNR3kthKYn(LaU0+*XHuGGpP(SDHW+w(2HWifAhYUaZt3%O*lCLPj&sIoP(z}yXnQZf--UF&@^IgLkMe!=t1dlnQxY#$%rviD?q)s-> zv)9%+jTWb+*oGzDX{oknHP{Ms2lsihcJ=0YIm@iowT?zyGSRH0XodA@vcX}kvcgOX zt!1?iT56>E2ps|AVjZO7Fw`}SGbF(^oz)?kgzqN#9}qNaPFZcee3__H5H5`}F<+B> zN=t@msE?Sb(jtWsV76E-r8cvz+_s^*78^nquS%|ff(*&!*3$a5MU}PpmKb8b)ueZ?Y^F)lvP$YSrLVHCp@&puae-H0D#ZmZ7P2gMp{F!m zG3`uwmp`ZyUn5kmO;yYd^Kdc2rWs}E7v>JtXG4VrS7DnaU}Y?`HwxudSOIGQ(n=4k zYplk9X$J6Pc9=@6PG!J)8Jl`EGqWA+P2Z-?!|v9Jk?(&-q8;?m^@3cLa(lpQK=?AA zUtgoJmWG2@u|a{9$&oHaxQaH=PN0TeH!A(*TZdsT$tPcLm}(u>zKgrUf8G$G(MDI& zjb3_7%PFdNR9MQa!;EuD4{|*;fauPGsmijpF3aoELa8hn6N*ET%UiL&ZSdJ_8|ea8R^CaBbiLtInr(Bgt#nF?s&1upVaBp7b0Ky;Bh{ZGUGEHCDbXIm zT%5gf+2Z_+oV;sOfWcdcER!iKvv{P6)t6{RnOXT+%0-dSkd{_m^~j%tEpk;OyE3-n zqOhQ#$ouAn&&>o(Gwap~QaP`k2})BH#T)eI8tl>4vmaYIhs~C6n+;|U4i^6l@W^!R zHryZ|{_e?qhqcb?*f4mvk?yFd?0W=q^;A0odCK*1PrW|!IoC%%_xi}^T_1UxirmM3 zlIJMeSKp>m_rY}(Rrkkr6jk@lbrevO<^)RyoS`Kn527 zYC9evWUU*9+>j#kz1?bAKgdx(#|Od=i_P&aX3AT+yfBLv{Shmi>s>M@KNEKYuc@d()zYHu4C6>< zl&orB@$EU+q87tk?!KdWjz0U&kvh(+z})LCAP>+gTWNV!QeCZpK)useRmZ|*(vwVc zS(VLN<78>2wwiLQgGKNhlZEP>J-Ocf#=2SkXo@}k63b)Utt7*Opbsnokoy@hxCu^uBsko&*Og*YB zR*fo^t3{nNREfc1safksS$sNU&nI!by^=Y`7>2eoUlkd+bcHdO#53lThZrZ<);rC$ z6=q3rUin@bjI~!9$J;xdW6nPj@nX(rD9rgZp1D{05c9dV8vJSkzqGJ8*49^J_Tnq> z$z+xIq;nPd<_%Sb-$YbfY&E_e;FY1Y#EW=n5O~pYW59QK%6Es&Lbdd`M!vg(8&A?a z>t~qDzl)GAX#GwDn2>R^`6~I+?<(qs=P#9~d_3}+%Rln+9#r(G2G7ar1WPHNYs=(m zJh{5de7IpYNHE8XfS! zs?&(h*XR|#{&OTbyfy#|z4x|&$vm_hVPxJ3tMUzcy4&4=o8x#oi*TI{n;=VFo!QxF zx0-D=6}7Z2!*5A=LXz5t%8sYMR_siw@r1YmC2g>LcAFhfIvXg8abv(hsI9GLKQeRR z_hDu0k%7IA!C)>b&MT11OOu#4NA|lfMvN!U@~prf45#5%sgff9fX#t>=o>a<3Eo_! z`n;3sYlei7A5+ga7qG@i6OY*@{RqcgB>(mdKL@J?b7}LVJlOVEA~^*m$|~z?)+>*j zYvuMz8{MmxoP(0Ir7`0tEc8^J^orZFPWC$v*=~j&iz@>1kI~t)aY?gt&H3~QJ%b*4 zoAaRYH1Jk6ft&cjJw zM9p(JrHYt($jH>Pz(mY=#y=7niCk&5*yZ0S3@hY(kU6XsHauHWektI$PT!vku%9yw z+v_#fdwjYMyJb8$ftkwk3~yT4t-TVX0vTf+9X?^rOl$n2*ys zQmq)6MP?$Wk!zEF4_ZE=q0W`dc+sVL51y;FMjrR7p`0d-Ir?z~>y+U&W$?AKbp?2c znPTvk!B>+bYJ5J5Dv^&UIsMSZ+h&KaW=NClS1!zKRXsEunLq2s zZzTtRs6#W%^=n&I`9II_TEyhLdjtV^Qva+moRnV=K?6`NOW;fTRN_-evi)o8yMJ2A zd=Fncv)mDu{M0fmD)K#m5h&Ru3Ej{b+*T+X|B;F+KZW4-DSoyej9YQh$omx9>RuZa zFD`YimqPq+mWI)Ze_}-~yb6Y)^rMAgDCLVal_LDp(zLD8#qfmQoyYE4(LJHT9-Uii z#c#;1gV$JInbz<4Pp=uG=XtT~QR&{p}mm4UDb{4ogWQaS2H5R80Kgnk|2OY^t$w_*;(KoxYw%R(|Qe|zx zPc^NM*?6M54!@wPo4p)Ah{#-JE?Sj88?O!2te;K4kSN3_oOenxXCmS>7;)i464&OBj|jY-YHPA-%gquXOEYxS!zxhHo%@ zli_iOCm5b&c#7c}hAxKZ73Z;iLj9^Ib6jS;n zh9bi_hVcv&8PXXtM4!qqjUl}YM(ODcjST4wEK1K~Sj=!W!!-;`7}7hHL|@6UilLKX z1H;V>n;14T+{SP_!(9w_GklI=E5p4EQ(uwmO=Gx_VLHQXh6N1QFf3tM&ajeU6~hLG zn;AASY-YHf;ckYl4EHkJ$8bNxHyOUg@C3t?3{NvW!_dX>9K$Y#-3e-0m85F?jhlHjo>8QkMo-d58@q6!XMy$W=AVmZfEGC^ai{m zN^xKd!*i6rNFywyIB*xkE=tGYs_7I5?q+y}(yIg<#wDYcVKKwi4A(H!LvQ2p?yQjz z@BHQw&PMwQjc7mN610!78t-Tl*5O@Q!kv(l@L9Y!Nw^nhHW2;j-hESp*>t0E{HWfv_SW4p@yNT&a=X zIS+Ue@5&<{uo-$K{0Mp^{4c!oNw`aX_dEcH`xz-d2mMZXAKFWZmrUuboPg_0XV$2Ns8kgZNhxC6S}xL5bwnk2IDLWLcFYd zif}C2O$hrsO$a+YLkN3t5k}+PX~JnZSA;Mg@4^$}o%KG#M7-Ndn2dL(3GveH6~Z*= z@nv8p=2OC@ct4mh7wa403XBWFLcAwSSd23O2v=f0CHywtuO) zgq{g)&@&(_+yMSLX5{2!k@!l z34euiGYH>--4gy9?^F~12Ky4ilQ`dt@O_*OM))!8n($AsYeE;!ARs)8vs(!N3Ogt4 zME?_hiT)>aqyGuNLjMzLG{T33qcp;4LL44^hVVv>;3Ax$5zZ0f;NdPpQ6qE{Mr(vV zLd;X26JoyUC&U5KR|qi=2++;VI3Qe0h{L9JgqU~22r++z6B;qD2y-y52$yMuNrade zMZy&rUxYZUJDw2pULqk5E!Mhbb!c6CI>x#lbLski*^#;gHuvsh?b`RYx2L+_>QKUo zTsV#kPvXK6TsVviYq{{1FNb)3&V{?V@HsAgh6{hlg->$f<6QVHF8l@;-p_^ia^dH= z@GdUAoeMW};musw$%U)9a5)!V!-b2va2^*na^ZzsIF$=0a^W~GJc$cOaN#g6tmVR2 zzTouFg}b@%IWByL3xCLkPjcboT=*?6{00}^&xQAL;pe#UE-t*C3paD&&0N^Yg{!!5 zITv2Tg^Rgx9v3!p;e}i{l?x|w;W#cli3>+?;V>?&<-%7!=k(8oySeZ=E_{Xyf5?ST za^d4#_$@B{1{dDXh4*sd=eY1LF1(!!H*?|5T-eEltGIAEh2gZqW7r|Ibci0$1v;DT zrbA(-a8poD&{CnL(Wu$E(HJbonmq3B_f9%O=l4v4w;vjB3NwYc#L1dP9{0%}5&7@+ z=u(AQUwmLcA{>?Tb*{vNl=Igfak9sK4*8lz!mQ6hVLvp*G{zKR8s}PcFxnIknqT$A zPmTuFFF~uD<8i+z@oc3sw+TrXr7~xPF%zelA|{S==@#l1g`AR0zQRhP#AMBF9`^%M z$@_ccQo_+$=le1uOjO^5$)SVwJ&aQGQSSpix;a$CXCEBt>f1tcg_*{iM!OasOfZq` z8^ARIaycN0OnF(7C8BanrD#e3MSpL!DOhU5XT8U6ICk-4yZs2&8D^S*bYW_+YgNB? zG}YDKD<0I$d3o`de_r0_nG?$4F8)BE0Udf62=H{eyhDeyIqJF4fK-V>V;er7^% zOVs;40UO64HxRi2$PJTn1E1ELkUN8NJ?`Ik|I~GNPS{+%snO_hKi9J+r_rc2=^^ct zJu%dh7^x*O0ezZ)K+`7&i9eOTfAJef@ga)n7Z;x-?9*rx4(8{`T<+`M=E_?djFt$y zHiGNio+ek$(v8MC7c0F$J9FG=(^9?Z#npxVv36tb0#n;+kNex6$b-R`!-S07<*p3S z7fJtD50(l>sYQdO7P3-{S*iKCsjm4bmF7yr|3!nPLQrbXV5t;VYC0>W&z74c);qg}Bqu60G{1c}j0 z8;zucH@brk9O({tqz`?cI1S&Tfd6ee_MyOO@ZD2!W;T2j!g|=44n7-xBH}6VsR&oW zU%?h99`VKS#}RITKLtMz@jKu}(40p6Irx0U%i#;-aMn67{E)}}&OkWEe5Orn8)G^b zRSWyP<(8)x2mUD}yTPdGd#k%-(#wkzkETx)CT333oN8UH`8{X^`;jn|4>W}zO1JG^ zJnB^X!HJclqM8x{{sbLd)VMT#3wy$k>{vYOygO5i@m+W-)3z#V>*7EgM#1H9ji&N{ zqJFSAH-gLY_qU9#n`biqw@1um+ z09V%<&4LrfniOHiS7%~vLd-KOV{J1UqU^D@A55HP5i#-yw$dD-HLZ-AU`n@*HO1I& zjCx}64X4K+oB?USylAn-+LlgyX7RXFkqv){%3c{``$J@`CDavq5cBE9Xq#v%vn??F zCh9wp9`}8i6Xdys=5za@`lVw{^*Ik52*T(J6gL`EOpZK{`}K>~q|HX5@6o0k&jchT zp329(nQk9__|Ad;fb=t7~;GrPJ7o@1{A+bTR0%J}}x8 z6B&uvRu6Q#bA467&gXjqHa+B8Hb@=bott}h_3p*NrhpHY=HF+Ga^*c+*_LB>HdIC4C=$-p^eCO(n-_y?&xN>-!Z<6ym|Fus1?iQ*iNHu;1n^Ddj|FZAh5*k2XkFsd@zRM;OD772@c?}EJk*s&%x zRi+)jF-NPvk+opsg-NcdQV*=`*WG~C;o?h`nJAqwSo*aKLhMT=FI5uHq109>)qdoE zaX;jp7ZD{Ji#%_Y#-4@EAE%nimG z8kwUtU0jW^b~!A-)L$}l{L+OfffY3JJnqlVYcFRDSmVCYUe*J51H*u(3);&%V1Xwz zSC7(nRz6!9Qv&@azEt3GS3)|HfA4(Ui$K4)aBt*PH0EoBd0CGP%KD}xt8*AxCz=v+ z?T0oQZ>fA3>wUN>s&ZQ14bN+mqe?a#nc--60Pjh+P`_7*@n9&f}Fkz{%V@tzEqh`n34FNkeje$Ed z8nrvNGzRT>yD@l&W@E^XjE%vfZU^l~)}0S>g$?p4XS~my4~4Z0NAqvRnWkuK7TQ`0 ze;@p-@c#)^e=#+0rqt1k;P_b}z|3JSHbtKZbFNfHpnuM+fXj z9JojHIApjRcoLWm6kwytz(imKFdsPUygie4Sc!S}AJ}Y+t^6cp%!kBdpwW$=Cv_#5Dxz<#Q0iEz}7{+_Z-xLhKP#ZKDezS1=*_g*87 z9`DgIA@|~HVXC!+M&HXNF(nIAVk;J4!w7k36weG!`e@TdgiD z%_}cekID%YC)*p1x?JI@O~xow3hIgK5={e;Ee-egXuNg7PlH^$As5!{mw$|6kzQgb6Ffc;4Vc-=53z_i19q!4Q)qU+->++$SvlbT1oZgmO0*E$U`*KQafhD&X8CuG zL9qKP7&iutzXI2Q`{bn@TyqS#w_n;~%0BqzQiCZ_jDLNjalrlaOM26ZCDE>U(+cEo zMt;G;OH%%HDgQO(M}s096nB843KVZ1?2;&^Nff&!3Qf$3B?eQ%K976xH?*Su{R&;D zxw;abfBtYN$}U6fldeBAnFieVU3$FjGVL-@Gi`Fy++I9IbeCY253y(;aZ%b}3sD`f*AKNzO^0rY4PiLDBV64S={bcEV#+YX}8nw{xfIAYpg$=mR^}d!PqSpr8 z$1lAK{opzYS{`ugF1?Z~n!Z{+;C}Pc%Ut@E-WOT={!1@#>3zLFVCk)wp6Alf^*)32 z+xr7sa!}jjmv(b`ANM}N$~$D+S$fT-?Ogg#dmm!yrI)sG z>96#DkEO4=)Xb$n)4PSGFTK>nrGLNoUY35_rOjOW{k@GWJ^4}tm%ahordCb6B*d>e zWiox*f8quBEwl^&+SqTr)ij}B^NU|x76RyM?-!R7Z@`{iy519J^nH+<6>)0Qlx)*) zE(Qj!Fh!Yyb`H41dV`+T9bRP`D zsrb7vmBv)@-{Va)4`A2+*il@69f$uN{DCOUy_jdr@acG7@@-%Rd?oWmz>g>5TYMA; z<^p4YRK^5P@wYTMqZ!x=Tn41QB9$w_K8G+2cn6TaeN+Z)(BKSCU>@QQU_at^AYJ!S z{50ZDAYB{Mdb|uWQhFjD_+7?+Q3T$C__>?0=LEhBTnP+06leB#y-)#J@@!CsNuvr(A(z86V=ilT1MZF8*`WMsw-BR?PDd!bcTR4ONq0Fy z_}l8x*L5ix*w5n<&4%t3CZhPVy8!>~-J90U#7-wrH1+EiZ8ZL|Kfd*k{o0lR_su;t zhdlQ6R4JEcn6W*vgJE4yj;YX;Dc!O7;>r}HW2FU`Tfy_|?mr%mLJIAu2Hc-@-->Zi zC{enujQ65E*FF32jchM8;Qrt4*(I8N1MUSqp=1{i9>DXjzd*kwdVG@%I0iZu&8))fKk?C`zHro&ca3G<=gLH~GFky`5gv0< z+fG1lK5i^(%S*%kuujyrYhwIHDx>H?>VK4J_9MeR*CE44oD5g+oR|2GB*O`=%n6j)>_>)G*CE3j z9KQy}ZzLIh$dxgoOp6~G=3IviJ2`%z&ye|zB!ihNa|~rp`jH{xI%LS@_}Ll1k!0ZQ zVIj)w^&`XI`iI8sNc?zv=uVLNjZ}uWhc{8?b3Zct{yJpf?V*zK8%YM<9#T=}m>(Gq zUWW|4J)Fby9^yBW3=eSqcK~Jf`H`XJI%IHg{7M+Vz9qBHYq#v^pt)3sbwJbF+V(K< zH0cc*f_PF0U(U883e`yo`oxl(GIQGLF3t8BgK9KdpUg8BeHWj1Y$OsJjLk zBf_8T$h(S+9d4B!Tt$!cJjI`kd#)nmr{F(QUz3cnSCR3p>yU99t|^o~L=AXSKhl0; zJur!dD}ggv*b0ni;ZopK7B&N8;1glPR6a0$Pp1&xdY0^cE98;(g9rzP@97K&O`r%& zKhm||?YYnmJ*|PSg4ZL@u9TPTyS43kl%Irj;zj#aA$=$InOi%ipgu~YJ>`CsT@AY( zEMI{7(_7nU@A)VzPvJm4(#4$}=_2-3>043Pk*=_Q&xO?}zYsnR^^i@G{KSjKn-a~&pIErVoyidcjR%c z+p?!4M0}!Chw&|>Ki&~`YFT?f_JD$ZXNOjNw4;y0CGwmlwe>)2TR=MI25j$xg}d6& zycybK&v)otPjrTXN64`!IyF16Z)|Dm&}g=H3i{Twg8uv9x4lE#f;tX7-4Sx&k@k=S z|8w^K1CO{yL*CCIyKoHY;gAEe%>31MmvHQ%j?o92T=*JVhj8G2lz#?zmrE0#+y271 z*0!C&0j>)kPv~gOm1jJjheJ?zfCzfXCWu?5ehEAEXnWsdN4h92IJ~uu>bebe5$%)d zG2s1h2hsiwdU+1d4|ZehhT~c#4t^WLdh|KzLl^#Ndj#5{)kjNn_>XChFL=H~Bdk1& zPfvsvpieZSvHitp%zek2FjwyB3_xDM+gm$FAwNiLZ41*whvMRPZTMDKfKYf=2;bVF zLE2XyPgFobR{O4BC%R-^ZATwG+OCKFRN@(kpl|7*^`j(xPe%#*A_UhgbPW@tf9Gtm z9rd7L@T9X-O+;<`|k_8p?9+F(`eu6Ci(hIhwC#z{|D4n zboNF(<~?4pr{g%-_)~vS|EA)akm@RBIggoeO}z&8m5F%)^TxREb!rQ?ga_$c$7#gYn?gXV!99>L=z???2)VTSt+<@` zL z{cl58$MV|43@wsw$&Q5ZogHE0nmS1j;S#?iUALp{v@X5_{40Euu;MJ)s|M{2D1c5& zXl@lAHrnq;J*{mYe*ybXZ*Je40siU6b}iN=N*DAGbZ9N|x>Won+5C~NwLr|{5>L`4 z@g!ZM?GN{3|LM&Ka^ilCc12SswUyS%+fkn85ignSG7lmA@h8wl&j6u|6*N~r91^~z zo%B!hXGr+lXEm@d$R0}a{e*NQVr)Ur0YY(`R%|s;+p5qW8gE*p!D)ETcmY^)`kGXlTttEAWvXA>1$_4 zfZ>5oqSr~|MxJY_-JcD3u>Q8T-Ayus_6yWcGARAu0{&!w)Q3U2!Ct@B68iG{>FMwr zcs`_sg5>AM-FO!Jjr(=>jNG?Os#Kas>iJ1XGUVRY~CZ=NRHx;yq$nMQdA z{*61E)yZBT%$Hs}%#@BK6J%iDSX!_kU;4<>0LSu1 z!gvu8A47?sTAnCQtw_L$It{a|4LG72hat|Q&pKFZ>QHNKjZkf?873!-(ThC2h_610 zwi;17gGiJPq!Ht%+7hSQ5|RY}B`oFZ>g!ObPAWV2^_L_8hZEOTia4L!Do(AtdcO3b zC_ij6=r_uhG&{F^lgu;u=JrCo}tP#xPBIAi7RUc zH7nv>O{x2n1blY`=V#%VYMlD6wi7zcni0ZI5`@P34fv!(om~#-l|ZshaI7uGw-khR zcI(xc3@b!ZQj%CESvPgEr3&xHmp6*}EA#TaMG~bWU!>z!h_DQ=-CN6r!BgwSveE@2 z?0;%i75+`Ni_0r2po0Zdk%r?$ZRJ)9h6>6-?1P8qFA(W<-~y*Z%qbG@%qmBz4XMQsJrj4NXqis8mq7>$7s%6yg<}9Ol`QXfBq^bLBV*V)luuM zp9Kr#lkwxF&yhiMLWx|rA;&P|gi4~TrI;$AZjFNrL0<)ob4-SVBORb`Gs6EC+Y;3F|13ncX zQuMB=<=+-fq}n>ntx3rhB68H?C^jWxTw>mZ3a#am6^eLe9w)#r5DPPI_nEmzE>%!l z=cMme$$k3|Freehg&ch4j=nsELs!a0oL$43$QB*U=XSKr?qe@LhmOmHw8XFicpF^S zDR;7Frlp3~47``Vo@_D34^51~K1_h&NHlV<7vT_ZTbWhdAmU~85h+qephz*Ik0eQ0 zcl%V7Br+*Pe0Z#~wp_f&A}?7L_)tZ8G`_5;`i#N?bgreeN*ZFrF%9)stjOwgQd98- zI+_+?kB-`E%-Z<8SS=PaW|r(&D}M~`np*d5K_;6;rx3fZvuaFzb(k#q)B;-> zW<0A%pFA5bPyRfCPp%%E87>F5;Y zG;j8?iFu45OFBVpxJ-YasTeG2vtj&lpC4VYK=pBh_yqa01#C})4;CyC3vjX>xl5TvLxFV1}A{q`DVi)j;=J2S>42fmyftekWdzZrT zFtjbiF?aa*6dtsVe9V%HX1L>rBpJDLe-Qt-`?m)Et$}}Q;NKefw+8-y(trn!+H>W* z_{}NYDT{aOR+I@sBmC4-K?s8X3;aR&M))lFkz5eUUW?n?3K`%NU%)dYV2Lo~+913p#LPvLz@Acc={;Sag+IfO|DqUqHooS2@uaa zg~2*JQLq4Yph5N^lWNuz

fKBj<6A`BK z!n(HM_Z}=gjw?%Nmyp}tig5+M8#Fqud?eBeI2+KRY$8{FGs+)_4@X)g{&B_phLqjrjno$9v0XJ$RG~+cB0wXmOHBkY#1PV!Ym3WNjw3G@-m3V9_B$YST z&GAkIe{48HLM|@GV{keNPK_46oVIJVkR@06fiSiH_z!@-+WZIda5L z2R{Q|p`-bdJk6s-M{}-1N8LueDNPykt0|K?3X)HOSLkR@M?Nv05do-9a`WMdj_SGc zkn9s_abQkioq;&5A=GACFUZq+p*V$Z84{>C(S@}#kFesXE^>FkQ<&&zER%1Mm?HsB zk*@+_YAa>YoKHR+1r<`NmuPF@6@Ii1k#{OeMjp|TcXD(zCy*~en&OCt+(vlfOZCuP zv>m<`VZ|xyD7MW~y-GUKRVfiJZyUnkWmmHLK{s28aCAx=l&tCdF!w1Dj_&^e`g>-; diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r2.3.3.so index 9fec924b9b2a1047929154630f2464aef9178890..1868ed2c8c44a1ca8b46879c68a6c5afa971c05c 100644 GIT binary patch delta 8490 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 Id+&hsZ-uZpg#Z8m delta 8511 zcmc&(eO%Mm)xS3+5HM&WDDNa8P@ozT3R-*xm8BrQP+vB-*%cIPsJv;_BB%jNThuzS zS6i#nhU!+_Y6nxEX+Ki!W;ff}4m(}#Gnqll3<3eBHnf#w-y4G7_4)rOB|9a6R8f7nMu*p;Cgc=bI8IHUWF_Ou#t$I+JeEBA zze5+VZe@;f(W>GaLJ$Z~oGvEuNr_S}rg^MHX+TsPlm^uTp}~n7jGJ{RpO)BOV6#=T z>0!22rB`_9p*m0GbUSXfA477v|s|+ghc1XR=e1HJ-v0396t1_z|)+>_| zGK)2gS8H<-oLH}IkB*R9p^NItgzRG-5u~OHHXLM-+*`?#f|FD{Mfp!j2HmT)goLt^V6`f=`eF5VkqN6=LoiR& zwqOJOnDycR9E+M@p>R9FK$Yy%32I7N--L9@-8z;uG3m*Cp~rz3O1)720VbiSoRDJK zNYH1X`MoPgM$EH633F;c$XCM1TzwZs$YFMT;^G)NqC7ggP3WvynC;oogj{}}MTbPI zwys4UqcRW1d&ngPTNq+UE`T%~Qr^TzNWD30kRIN$9`jz0jKd6gYL$Suvg09Y`V{*# zWU*@9u91byJzl^BWHEhcI;~(Op=woPA+Iyy_j4m5FS3Tvr)eh}4o#P|SFqV(vy)p_ z5u)*$+(cH&D<6*I2D)Oaeb{sszAslq7k0njR}ODWXHqRONPCp;-kKWKpsG9jgIoKC~pu_?R7Z4CUosY z96}7Qql?Clbv|6oq9c;DuVDFCqcI+kMnt|EGsDez`4*PDl$AsnR6})y#JYBH9WOc#HB0Z~L60xML ze8Z@fzO-2n5{>Whm?H&*Dqo;(#(lTwpX4CU)ruiRKvyumPH zP?0v(u<^Oo>kaIUC66-W(wX#?6D3Q(2(VO}Fp59!xgq`Jl^fMxpXnOK6#_07uvx(Q z0?rd~u7I-yoFU+}5p3}^Y!nm;0@esPRKQ9B%LPmXJaq5jUjXu$fGY%CE?~2O^97tI;9LP`2{=Q*X%?Yi6mWuoH3AM5uu{Ns0TTfa z-4Uihz;-YGF<NpPglppNVtc3h}3 zntTq1IO@Yc?UPgn+7wfLju}moU%8!Q* zHt76hJo_p@?VuD0mV**ta1G_dp!q20gBIbeP{sP5iHn%tmmm3yxs%Ukgpsg$k+j`9 zmwsM0KuLLwTD*x zH9Tv1OwnIMbp-*ofEKsY!RDE#1)6*POfpPmHbSwJ?J!TFud=h|xLMUbk}SXGHv7N} zDd`p-o<^nX~$v++yE_ULWg#_fE!C&4!T zfqi99T8>OBG1>AWY>($~59@oT=JP*@$V`=(81lx8k_H53$Ze+zUZXu^0>Z5pWIoo8YIQKLGv;_+FO0c9QHL8bUr} z1#5K$>u--Fb$P4QRBcW>Jw97%9PdqagV%v?178pR zEAVCD7s2)2<@5A?l3kM*Y;WF@sWbntU*Ki#BepxMg=*YRqdh*SD)SHBgmP)BJ$6B~ zc1xzlOpTg+jH{a@re2~N%_6rm+`f%YhBL! z4!=Xb4MQkp#m>Pt%GWq$lGi7hUCvqy%u}UQOLP^PiOlVM&whO

SI!wv*G>hhk%W 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 diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r3.0.1.so index 7a3d126cf9f8712ac282ce791d74d4f98015a8fa..295cbc6b03765114cb9b7f315621892f30faf760 100755 GIT binary patch delta 6138 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 lr}Jk*WzJCP_LydscpL25;9)cYs+{{eq%hUWkP delta 6030 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 diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.0.so index 12f2181374fa1d3fc453d57868d39371f7e21a1a..d34fa65d814d3393c7c7309203f7a80db2d135b9 100755 GIT binary patch delta 8751 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 Pt{GV-pG$b>E#dzGf%V^x diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.0.3.so index bc2683477954115bb5e47ff0b533294f7a4cdf50..b6b8f4df50dacf37d80880b13f22f7ecb0d3f672 100755 GIT binary patch delta 6195 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 G=KlwW`e~{F diff --git a/3rdparty/lib/armeabi-v7a/libnative_camera_r4.1.1.so b/3rdparty/lib/armeabi-v7a/libnative_camera_r4.1.1.so new file mode 100644 index 0000000000000000000000000000000000000000..1fec795114118e2d9d91e679e3d2d922631e3e06 GIT binary patch literal 45232 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 So-3PM@k{Vtc2CG%y#EF~>icj7cz( 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 M+bL1V{}j6a3k87~s{jB1 diff --git a/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so b/3rdparty/lib/armeabi/libnative_camera_r2.3.3.so index 475a9860102045599588ccfc741f831599636c2b..78c104c114703a6822e55143b3e9123fb167f71a 100755 GIT binary patch delta 5894 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 Q+(WVG0$Ms3y?dVjKVPtn_W%F@ diff --git a/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so b/3rdparty/lib/armeabi/libnative_camera_r3.0.1.so index 1dbabe40632af9b2d44ab9163c15cfe9e7c0d5a8..c5532e36b5e120b3de0101efa1a3c69de58c5bc2 100755 GIT binary patch delta 9274 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 L)E6_}KS}==!U$Xy delta 9292 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 delta 6224 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 delta 9265 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 KlSS{pOaBiqyy=1f diff --git a/3rdparty/lib/armeabi/libnative_camera_r4.1.1.so b/3rdparty/lib/armeabi/libnative_camera_r4.1.1.so new file mode 100644 index 0000000000000000000000000000000000000000..352461f82c281c064327c011a55b85a2e3c6cc6d GIT binary patch literal 45616 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 CGY1U- literal 0 HcmV?d00001 diff --git a/3rdparty/lib/x86/libnative_camera_r2.3.3.so b/3rdparty/lib/x86/libnative_camera_r2.3.3.so index 0a8b0faee1a210b52210e137061506dfc24d776e..4e04a3e23ff5889180a3dfab503d99d770eefd5f 100755 GIT binary patch delta 10598 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 delta 10467 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 k0$P34qYt+{8Mm{n^NO_>}Bcy0PhmTjQ{`u delta 10389 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 E|2C?oRsaA1 diff --git a/3rdparty/lib/x86/libnative_camera_r4.0.3.so b/3rdparty/lib/x86/libnative_camera_r4.0.3.so index 7ab37360e05361da736ce08ff39fd7db7933655d..c00c9570155bcbd95cbe4d6c95655a212eec4374 100755 GIT binary patch delta 10555 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 delta 10499 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 diff --git a/3rdparty/lib/x86/libnative_camera_r4.1.1.so b/3rdparty/lib/x86/libnative_camera_r4.1.1.so new file mode 100644 index 0000000000000000000000000000000000000000..df22898b45b2efe5d35083dda1b9b303d8e15af3 GIT binary patch literal 54080 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 literal 0 HcmV?d00001 From 640408ebe77ea263a980fb414692ceedc4555087 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 31 Jul 2012 17:17:58 +0400 Subject: [PATCH 13/17] added FAST<5/8> & FAST<7/12> (by Vincent Rabaud) --- .../include/opencv2/features2d/features2d.hpp | 11 +- modules/features2d/perf/perf_fast.cpp | 6 +- modules/features2d/src/fast.cpp | 331 ++++++++++++++---- modules/features2d/src/features2d_init.cpp | 3 +- modules/features2d/test/test_fast.cpp | 13 +- 5 files changed, 292 insertions(+), 72 deletions(-) diff --git a/modules/features2d/include/opencv2/features2d/features2d.hpp b/modules/features2d/include/opencv2/features2d/features2d.hpp index d8cd2354a..a191ca223 100644 --- a/modules/features2d/include/opencv2/features2d/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d/features2d.hpp @@ -473,12 +473,18 @@ protected: //! detects corners using FAST algorithm by E. Rosten CV_EXPORTS void FAST( InputArray image, CV_OUT vector& keypoints, - int threshold, bool nonmaxSupression=true ); + int threshold, bool nonmaxSupression=true, int type = 2 ); class CV_EXPORTS_W FastFeatureDetector : public FeatureDetector { public: - CV_WRAP FastFeatureDetector( int threshold=10, bool nonmaxSuppression=true ); + enum + { + TYPE_5_8 = 0, TYPE_7_12 = 1, TYPE_9_16 = 2 + }; + + CV_WRAP FastFeatureDetector( int threshold=10, bool nonmaxSuppression=true); + CV_WRAP FastFeatureDetector( int threshold, bool nonmaxSuppression, int type); AlgorithmInfo* info() const; protected: @@ -486,6 +492,7 @@ protected: int threshold; bool nonmaxSuppression; + int type; }; diff --git a/modules/features2d/perf/perf_fast.cpp b/modules/features2d/perf/perf_fast.cpp index da75f9d3f..28f0cccb1 100644 --- a/modules/features2d/perf/perf_fast.cpp +++ b/modules/features2d/perf/perf_fast.cpp @@ -22,9 +22,13 @@ PERF_TEST_P(fast, detectForORB, testing::Values(FAST_IMAGES)) declare.in(frame); - FastFeatureDetector fd(20, true); + FastFeatureDetector fd(20, true, FastFeatureDetector::TYPE_5_8); vector points; TEST_CYCLE() fd.detect(frame, points); + fd = FastFeatureDetector(20, true, FastFeatureDetector::TYPE_7_12); + TEST_CYCLE() fd.detect(frame, points); + fd = FastFeatureDetector(20, true, FastFeatureDetector::TYPE_9_16); + TEST_CYCLE() fd.detect(frame, points); } diff --git a/modules/features2d/src/fast.cpp b/modules/features2d/src/fast.cpp index 9495d3578..f496de3d5 100644 --- a/modules/features2d/src/fast.cpp +++ b/modules/features2d/src/fast.cpp @@ -46,27 +46,93 @@ The references are: namespace cv { -static void makeOffsets(int pixel[], int row_stride) +static void makeOffsets(int pixel[], int row_stride, int patternSize) { - pixel[0] = 0 + row_stride * 3; - pixel[1] = 1 + row_stride * 3; - pixel[2] = 2 + row_stride * 2; - pixel[3] = 3 + row_stride * 1; - pixel[4] = 3 + row_stride * 0; - pixel[5] = 3 + row_stride * -1; - pixel[6] = 2 + row_stride * -2; - pixel[7] = 1 + row_stride * -3; - pixel[8] = 0 + row_stride * -3; - pixel[9] = -1 + row_stride * -3; - pixel[10] = -2 + row_stride * -2; - pixel[11] = -3 + row_stride * -1; - pixel[12] = -3 + row_stride * 0; - pixel[13] = -3 + row_stride * 1; - pixel[14] = -2 + row_stride * 2; - pixel[15] = -1 + row_stride * 3; + switch(patternSize) { + case 16: + pixel[0] = 0 + row_stride * 3; + pixel[1] = 1 + row_stride * 3; + pixel[2] = 2 + row_stride * 2; + pixel[3] = 3 + row_stride * 1; + pixel[4] = 3 + row_stride * 0; + pixel[5] = 3 + row_stride * -1; + pixel[6] = 2 + row_stride * -2; + pixel[7] = 1 + row_stride * -3; + pixel[8] = 0 + row_stride * -3; + pixel[9] = -1 + row_stride * -3; + pixel[10] = -2 + row_stride * -2; + pixel[11] = -3 + row_stride * -1; + pixel[12] = -3 + row_stride * 0; + pixel[13] = -3 + row_stride * 1; + pixel[14] = -2 + row_stride * 2; + pixel[15] = -1 + row_stride * 3; + break; + case 12: + pixel[0] = 0 + row_stride * 2; + pixel[1] = 1 + row_stride * 2; + pixel[2] = 2 + row_stride * 1; + pixel[3] = 2 + row_stride * 0; + pixel[4] = 2 + row_stride * -1; + pixel[5] = 1 + row_stride * -2; + pixel[6] = 0 + row_stride * -2; + pixel[7] = -1 + row_stride * -2; + pixel[8] = -2 + row_stride * -1; + pixel[9] = -2 + row_stride * 0; + pixel[10] = -2 + row_stride * 1; + pixel[11] = -1 + row_stride * 2; + break; + case 8: + pixel[0] = 0 + row_stride * 1; + pixel[1] = 1 + row_stride * 1; + pixel[2] = 1 + row_stride * 0; + pixel[3] = 1 + row_stride * -1; + pixel[4] = 0 + row_stride * -1; + pixel[5] = -1 + row_stride * -1; + pixel[6] = 0 + row_stride * 0; + pixel[7] = 1 + row_stride * 1; + break; + } } -static int cornerScore(const uchar* ptr, const int pixel[], int threshold) +/*static void testCorner(const uchar* ptr, const int pixel[], int K, int N, int threshold) { + // check that with the computed "threshold" the pixel is still a corner + // and that with the increased-by-1 "threshold" the pixel is not a corner anymore + for( int delta = 0; delta <= 1; delta++ ) + { + int v0 = std::min(ptr[0] + threshold + delta, 255); + int v1 = std::max(ptr[0] - threshold - delta, 0); + int c0 = 0, c1 = 0; + + for( int k = 0; k < N; k++ ) + { + int x = ptr[pixel[k]]; + if(x > v0) + { + if( ++c0 > K ) + break; + c1 = 0; + } + else if( x < v1 ) + { + if( ++c1 > K ) + break; + c0 = 0; + } + else + { + c0 = c1 = 0; + } + } + CV_Assert( (delta == 0 && std::max(c0, c1) > K) || + (delta == 1 && std::max(c0, c1) <= K) ); + } +}*/ + +template +int cornerScore(const uchar* ptr, const int pixel[], int threshold); + +template<> +int cornerScore<16>(const uchar* ptr, const int pixel[], int threshold) { const int K = 8, N = 16 + K + 1; int k, v = ptr[0]; @@ -150,50 +216,170 @@ static int cornerScore(const uchar* ptr, const int pixel[], int threshold) #endif #if 0 - // check that with the computed "threshold" the pixel is still a corner - // and that with the increased-by-1 "threshold" the pixel is not a corner anymore - for( int delta = 0; delta <= 1; delta++ ) - { - int v0 = std::min(ptr[0] + threshold + delta, 255); - int v1 = std::max(ptr[0] - threshold - delta, 0); - int c0 = 0, c1 = 0; - - for( int k = 0; k < N; k++ ) - { - int x = ptr[pixel[k]]; - if(x > v0) - { - if( ++c0 > K ) - break; - c1 = 0; - } - else if( x < v1 ) - { - if( ++c1 > K ) - break; - c0 = 0; - } - else - { - c0 = c1 = 0; - } - } - CV_Assert( (delta == 0 && std::max(c0, c1) > K) || - (delta == 1 && std::max(c0, c1) <= K) ); - } + testCorner(ptr, pixel, K, N, threshold); #endif return threshold; } +template<> +int cornerScore<12>(const uchar* ptr, const int pixel[], int threshold) +{ + const int K = 6, N = 12 + K + 1; + int k, v = ptr[0]; + short d[N]; + for( k = 0; k < N; k++ ) + d[k] = (short)(v - ptr[pixel[k]]); -void FAST(InputArray _img, std::vector& keypoints, int threshold, bool nonmax_suppression) +#if CV_SSE2 + __m128i q0 = _mm_set1_epi16(-1000), q1 = _mm_set1_epi16(1000); + for( k = 0; k < 16; k += 8 ) + { + __m128i v0 = _mm_loadu_si128((__m128i*)(d+k+1)); + __m128i v1 = _mm_loadu_si128((__m128i*)(d+k+2)); + __m128i a = _mm_min_epi16(v0, v1); + __m128i b = _mm_max_epi16(v0, v1); + v0 = _mm_loadu_si128((__m128i*)(d+k+3)); + a = _mm_min_epi16(a, v0); + b = _mm_max_epi16(b, v0); + v0 = _mm_loadu_si128((__m128i*)(d+k+4)); + a = _mm_min_epi16(a, v0); + b = _mm_max_epi16(b, v0); + v0 = _mm_loadu_si128((__m128i*)(d+k+5)); + a = _mm_min_epi16(a, v0); + b = _mm_max_epi16(b, v0); + v0 = _mm_loadu_si128((__m128i*)(d+k+6)); + a = _mm_min_epi16(a, v0); + b = _mm_max_epi16(b, v0); + v0 = _mm_loadu_si128((__m128i*)(d+k)); + q0 = _mm_max_epi16(q0, _mm_min_epi16(a, v0)); + q1 = _mm_min_epi16(q1, _mm_max_epi16(b, v0)); + v0 = _mm_loadu_si128((__m128i*)(d+k+7)); + q0 = _mm_max_epi16(q0, _mm_min_epi16(a, v0)); + q1 = _mm_min_epi16(q1, _mm_max_epi16(b, v0)); + } + q0 = _mm_max_epi16(q0, _mm_sub_epi16(_mm_setzero_si128(), q1)); + q0 = _mm_max_epi16(q0, _mm_unpackhi_epi64(q0, q0)); + q0 = _mm_max_epi16(q0, _mm_srli_si128(q0, 4)); + q0 = _mm_max_epi16(q0, _mm_srli_si128(q0, 2)); + threshold = (short)_mm_cvtsi128_si32(q0) - 1; +#else + int a0 = threshold; + for( k = 0; k < 12; k += 2 ) + { + int a = std::min((int)d[k+1], (int)d[k+2]); + if( a <= a0 ) + continue; + a = std::min(a, (int)d[k+3]); + a = std::min(a, (int)d[k+4]); + a = std::min(a, (int)d[k+5]); + a = std::min(a, (int)d[k+6]); + a0 = std::max(a0, std::min(a, (int)d[k])); + a0 = std::max(a0, std::min(a, (int)d[k+7])); + } + + int b0 = -a0; + for( k = 0; k < 12; k += 2 ) + { + int b = std::max((int)d[k+1], (int)d[k+2]); + b = std::max(b, (int)d[k+3]); + b = std::max(b, (int)d[k+4]); + if( b >= b0 ) + continue; + b = std::max(b, (int)d[k+5]); + b = std::max(b, (int)d[k+6]); + + b0 = std::min(b0, std::max(b, (int)d[k])); + b0 = std::min(b0, std::max(b, (int)d[k+7])); + } + + threshold = -b0-1; +#endif + +#if 0 + testCorner(ptr, pixel, K, N, threshold); +#endif + return threshold; +} + +template<> +int cornerScore<8>(const uchar* ptr, const int pixel[], int threshold) +{ + const int K = 4, N = 8 + K + 1; + int k, v = ptr[0]; + short d[N]; + for( k = 0; k < N; k++ ) + d[k] = (short)(v - ptr[pixel[k]]); + +#if CV_SSE2 + __m128i q0 = _mm_set1_epi16(-1000), q1 = _mm_set1_epi16(1000); + for( k = 0; k < 16; k += 8 ) + { + __m128i v0 = _mm_loadu_si128((__m128i*)(d+k+1)); + __m128i v1 = _mm_loadu_si128((__m128i*)(d+k+2)); + __m128i a = _mm_min_epi16(v0, v1); + __m128i b = _mm_max_epi16(v0, v1); + v0 = _mm_loadu_si128((__m128i*)(d+k+3)); + a = _mm_min_epi16(a, v0); + b = _mm_max_epi16(b, v0); + v0 = _mm_loadu_si128((__m128i*)(d+k+4)); + a = _mm_min_epi16(a, v0); + b = _mm_max_epi16(b, v0); + v0 = _mm_loadu_si128((__m128i*)(d+k)); + q0 = _mm_max_epi16(q0, _mm_min_epi16(a, v0)); + q1 = _mm_min_epi16(q1, _mm_max_epi16(b, v0)); + v0 = _mm_loadu_si128((__m128i*)(d+k+5)); + q0 = _mm_max_epi16(q0, _mm_min_epi16(a, v0)); + q1 = _mm_min_epi16(q1, _mm_max_epi16(b, v0)); + } + q0 = _mm_max_epi16(q0, _mm_sub_epi16(_mm_setzero_si128(), q1)); + q0 = _mm_max_epi16(q0, _mm_unpackhi_epi64(q0, q0)); + q0 = _mm_max_epi16(q0, _mm_srli_si128(q0, 4)); + q0 = _mm_max_epi16(q0, _mm_srli_si128(q0, 2)); + threshold = (short)_mm_cvtsi128_si32(q0) - 1; +#else + int a0 = threshold; + for( k = 0; k < 8; k += 2 ) + { + int a = std::min((int)d[k+1], (int)d[k+2]); + if( a <= a0 ) + continue; + a = std::min(a, (int)d[k+3]); + a = std::min(a, (int)d[k+4]); + a0 = std::max(a0, std::min(a, (int)d[k])); + a0 = std::max(a0, std::min(a, (int)d[k+5])); + } + + int b0 = -a0; + for( k = 0; k < 12; k += 2 ) + { + int b = std::max((int)d[k+1], (int)d[k+2]); + b = std::max(b, (int)d[k+3]); + if( b >= b0 ) + continue; + b = std::max(b, (int)d[k+4]); + + b0 = std::min(b0, std::max(b, (int)d[k])); + b0 = std::min(b0, std::max(b, (int)d[k+5])); + } + + threshold = -b0-1; +#endif + +#if 0 + testCorner(ptr, pixel, K, N, threshold); +#endif + return threshold; +} + +template +void FAST_t(InputArray _img, std::vector& keypoints, int threshold, bool nonmax_suppression) { Mat img = _img.getMat(); - const int K = 8, N = 16 + K + 1; - int i, j, k, pixel[N]; - makeOffsets(pixel, (int)img.step); - for(k = 16; k < N; k++) - pixel[k] = pixel[k - 16]; + const int K = patternSize/2, N = patternSize + K + 1, quarterPatternSize = patternSize/4; + int i, j, k, pixel[25]; + makeOffsets(pixel, (int)img.step, patternSize); + for(k = patternSize; k < 25; k++) + pixel[k] = pixel[k - patternSize]; keypoints.clear(); @@ -235,9 +421,9 @@ void FAST(InputArray _img, std::vector& keypoints, int threshold, bool v0 = _mm_xor_si128(_mm_adds_epu8(v0, t), delta); __m128i x0 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[0])), delta); - __m128i x1 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[4])), delta); - __m128i x2 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[8])), delta); - __m128i x3 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[12])), delta); + __m128i x1 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[quarterPatternSize])), delta); + __m128i x2 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[2*quarterPatternSize])), delta); + __m128i x3 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[3*quarterPatternSize])), delta); m0 = _mm_and_si128(_mm_cmpgt_epi8(x0, v0), _mm_cmpgt_epi8(x1, v0)); m1 = _mm_and_si128(_mm_cmpgt_epi8(v1, x0), _mm_cmpgt_epi8(v1, x1)); m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x1, v0), _mm_cmpgt_epi8(x2, v0))); @@ -279,7 +465,7 @@ void FAST(InputArray _img, std::vector& keypoints, int threshold, bool { cornerpos[ncorners++] = j+k; if(nonmax_suppression) - curr[j+k] = (uchar)cornerScore(ptr+k, pixel, threshold); + curr[j+k] = (uchar)cornerScore(ptr+k, pixel, threshold); } } #endif @@ -317,7 +503,7 @@ void FAST(InputArray _img, std::vector& keypoints, int threshold, bool { cornerpos[ncorners++] = j; if(nonmax_suppression) - curr[j] = (uchar)cornerScore(ptr, pixel, threshold); + curr[j] = (uchar)cornerScore(ptr, pixel, threshold); break; } } @@ -339,7 +525,7 @@ void FAST(InputArray _img, std::vector& keypoints, int threshold, bool { cornerpos[ncorners++] = j; if(nonmax_suppression) - curr[j] = (uchar)cornerScore(ptr, pixel, threshold); + curr[j] = (uchar)cornerScore(ptr, pixel, threshold); break; } } @@ -375,19 +561,36 @@ void FAST(InputArray _img, std::vector& keypoints, int threshold, bool } } - +void FAST(InputArray _img, std::vector& keypoints, int threshold, bool nonmax_suppression, int type) +{ + switch(type) { + case FastFeatureDetector::TYPE_5_8: + FAST_t<8>(_img, keypoints, threshold, nonmax_suppression); + break; + case FastFeatureDetector::TYPE_7_12: + FAST_t<12>(_img, keypoints, threshold, nonmax_suppression); + break; + case FastFeatureDetector::TYPE_9_16: + FAST_t<16>(_img, keypoints, threshold, nonmax_suppression); + break; + } +} /* * FastFeatureDetector */ FastFeatureDetector::FastFeatureDetector( int _threshold, bool _nonmaxSuppression ) -: threshold(_threshold), nonmaxSuppression(_nonmaxSuppression) + : threshold(_threshold), nonmaxSuppression(_nonmaxSuppression), type(FastFeatureDetector::TYPE_9_16) {} +FastFeatureDetector::FastFeatureDetector( int _threshold, bool _nonmaxSuppression, int _type ) +: threshold(_threshold), nonmaxSuppression(_nonmaxSuppression), type(_type) +{} + void FastFeatureDetector::detectImpl( const Mat& image, vector& keypoints, const Mat& mask ) const { Mat grayImage = image; if( image.type() != CV_8U ) cvtColor( image, grayImage, CV_BGR2GRAY ); - FAST( grayImage, keypoints, threshold, nonmaxSuppression ); + FAST( grayImage, keypoints, threshold, nonmaxSuppression, type ); KeyPointsFilter::runByPixelsMask( keypoints, mask ); } diff --git a/modules/features2d/src/features2d_init.cpp b/modules/features2d/src/features2d_init.cpp index 0d884ef67..6ecffebd4 100644 --- a/modules/features2d/src/features2d_init.cpp +++ b/modules/features2d/src/features2d_init.cpp @@ -58,7 +58,8 @@ CV_INIT_ALGORITHM(BriefDescriptorExtractor, "Feature2D.BRIEF", CV_INIT_ALGORITHM(FastFeatureDetector, "Feature2D.FAST", obj.info()->addParam(obj, "threshold", obj.threshold); - obj.info()->addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression)); + obj.info()->addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression); + obj.info()->addParam(obj, "type", obj.type, FastFeatureDetector::TYPE_9_16)); /////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/modules/features2d/test/test_fast.cpp b/modules/features2d/test/test_fast.cpp index d991a2905..671e66d5f 100644 --- a/modules/features2d/test/test_fast.cpp +++ b/modules/features2d/test/test_fast.cpp @@ -58,6 +58,7 @@ CV_FastTest::~CV_FastTest() {} void CV_FastTest::run( int ) { + for(int type=0; type <= 2; ++type) { Mat image1 = imread(string(ts->get_data_path()) + "inpaint/orig.jpg"); Mat image2 = imread(string(ts->get_data_path()) + "cameracalibration/chess9.jpg"); string xml = string(ts->get_data_path()) + "fast/result.xml"; @@ -74,8 +75,8 @@ void CV_FastTest::run( int ) vector keypoints1; vector keypoints2; - FAST(gray1, keypoints1, 30); - FAST(gray2, keypoints2, 30); + FAST(gray1, keypoints1, 30, type); + FAST(gray2, keypoints2, 30, type); for(size_t i = 0; i < keypoints1.size(); ++i) { @@ -109,17 +110,21 @@ void CV_FastTest::run( int ) read( fs["exp_kps2"], exp_kps2, Mat() ); fs.release(); + // We only have testing data for 9_16 but it actually works equally well for 7_12 + if ((type==1) || (type==2)){ if ( 0 != norm(exp_kps1, kps1, NORM_L2) || 0 != norm(exp_kps2, kps2, NORM_L2)) { ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); return; } + } - /* cv::namedWindow("Img1"); cv::imshow("Img1", image1); + /*cv::namedWindow("Img1"); cv::imshow("Img1", image1); cv::namedWindow("Img2"); cv::imshow("Img2", image2); cv::waitKey(0);*/ + } - ts->set_failed_test_info(cvtest::TS::OK); + ts->set_failed_test_info(cvtest::TS::OK); } TEST(Features2d_FAST, regression) { CV_FastTest test; test.safe_run(); } From 4a4f90c406239e6d4735b91f2d34a2469220f564 Mon Sep 17 00:00:00 2001 From: Philipp Wagner Date: Tue, 31 Jul 2012 21:50:46 +0200 Subject: [PATCH 14/17] facerec.cpp: Added an exception to the LBP extraction, so now a meaningful exception is thrown if the wrong image type was given. Thanks to Eric Christiansen for reporting. --- modules/contrib/src/facerec.cpp | 39 +++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/modules/contrib/src/facerec.cpp b/modules/contrib/src/facerec.cpp index 183338a9b..78e4af43a 100644 --- a/modules/contrib/src/facerec.cpp +++ b/modules/contrib/src/facerec.cpp @@ -578,6 +578,23 @@ void olbp_(InputArray _src, OutputArray _dst) { } } +static void olbp(InputArray src, OutputArray dst) { + int type = src.getMat().type(); + switch (type) { + case CV_8SC1: olbp_(src,dst); break; + case CV_8UC1: olbp_(src,dst); break; + case CV_16SC1: olbp_(src,dst); break; + case CV_16UC1: olbp_(src,dst); break; + case CV_32SC1: olbp_(src,dst); break; + case CV_32FC1: olbp_(src,dst); break; + case CV_64FC1: olbp_(src,dst); break; + default: + string error_msg = format("Using Original Local Binary Patterns for feature extraction only works on single-channel images (given %d). Please pass the image data as a grayscale image!", type); + CV_Error(CV_StsNotImplemented, error_msg); + break; + } +} + //------------------------------------------------------------------------------ // cv::elbp @@ -622,15 +639,19 @@ inline void elbp_(InputArray _src, OutputArray _dst, int radius, int neighbors) static void elbp(InputArray src, OutputArray dst, int radius, int neighbors) { - switch (src.type()) { - case CV_8SC1: elbp_(src,dst, radius, neighbors); break; - case CV_8UC1: elbp_(src, dst, radius, neighbors); break; - case CV_16SC1: elbp_(src,dst, radius, neighbors); break; - case CV_16UC1: elbp_(src,dst, radius, neighbors); break; - case CV_32SC1: elbp_(src,dst, radius, neighbors); break; - case CV_32FC1: elbp_(src,dst, radius, neighbors); break; - case CV_64FC1: elbp_(src,dst, radius, neighbors); break; - default: break; + int type = src.type(); + switch (type) { + case CV_8SC1: elbp_(src,dst, radius, neighbors); break; + case CV_8UC1: elbp_(src, dst, radius, neighbors); break; + case CV_16SC1: elbp_(src,dst, radius, neighbors); break; + case CV_16UC1: elbp_(src,dst, radius, neighbors); break; + case CV_32SC1: elbp_(src,dst, radius, neighbors); break; + case CV_32FC1: elbp_(src,dst, radius, neighbors); break; + case CV_64FC1: elbp_(src,dst, radius, neighbors); break; + default: + string error_msg = format("Using Original Local Binary Patterns for feature extraction only works on single-channel images (given %d). Please pass the image data as a grayscale image!", type); + CV_Error(CV_StsNotImplemented, error_msg); + break; } } From 989631c5cc312c7d750e15b16a22901529a26233 Mon Sep 17 00:00:00 2001 From: Philipp Wagner Date: Tue, 31 Jul 2012 21:54:48 +0200 Subject: [PATCH 15/17] facerec.cpp: Removed Original LBP wrapper, because it is not in use and therefore generates a warning. --- modules/contrib/src/facerec.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/modules/contrib/src/facerec.cpp b/modules/contrib/src/facerec.cpp index 78e4af43a..6ff51fe89 100644 --- a/modules/contrib/src/facerec.cpp +++ b/modules/contrib/src/facerec.cpp @@ -578,24 +578,6 @@ void olbp_(InputArray _src, OutputArray _dst) { } } -static void olbp(InputArray src, OutputArray dst) { - int type = src.getMat().type(); - switch (type) { - case CV_8SC1: olbp_(src,dst); break; - case CV_8UC1: olbp_(src,dst); break; - case CV_16SC1: olbp_(src,dst); break; - case CV_16UC1: olbp_(src,dst); break; - case CV_32SC1: olbp_(src,dst); break; - case CV_32FC1: olbp_(src,dst); break; - case CV_64FC1: olbp_(src,dst); break; - default: - string error_msg = format("Using Original Local Binary Patterns for feature extraction only works on single-channel images (given %d). Please pass the image data as a grayscale image!", type); - CV_Error(CV_StsNotImplemented, error_msg); - break; - } -} - - //------------------------------------------------------------------------------ // cv::elbp //------------------------------------------------------------------------------ From 8d73bbb8b71843ae7669cc2e38c32cfebb50d2a1 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 2 Aug 2012 13:18:55 +0400 Subject: [PATCH 16/17] fixed 2228 --- modules/gpu/src/cascadeclassifier.cpp | 936 +++++++++++++------------- 1 file changed, 469 insertions(+), 467 deletions(-) diff --git a/modules/gpu/src/cascadeclassifier.cpp b/modules/gpu/src/cascadeclassifier.cpp index 61f5c9431..1f277f0cf 100644 --- a/modules/gpu/src/cascadeclassifier.cpp +++ b/modules/gpu/src/cascadeclassifier.cpp @@ -1,51 +1,51 @@ -/*M/////////////////////////////////////////////////////////////////////////////////////// -// -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. -// -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. -// -// -// License Agreement -// For Open Source Computer Vision Library -// -// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. -// Third party copyrights are property of their respective owners. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistribution's of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// * Redistribution's in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other GpuMaterials provided with the distribution. -// -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// This software is provided by the copyright holders and contributors "as is" and -// any express or bpied warranties, including, but not limited to, the bpied -// warranties of merchantability and fitness for a particular purpose are disclaimed. -// In no event shall the Intel Corporation or contributors be liable for any direct, -// indirect, incidental, special, exemplary, or consequential damages -// (including, but not limited to, procurement of substitute goods or services; -// loss of use, data, or profits; or business interruption) however caused -// and on any theory of liability, whether in contract, strict liability, -// or tort (including negligence or otherwise) arising in any way out of -// the use of this software, even if advised of the possibility of such damage. -// -//M*/ - -#include "precomp.hpp" -#include -#include - -using namespace cv; -using namespace cv::gpu; +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other GpuMaterials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or bpied warranties, including, but not limited to, the bpied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" +#include +#include + +using namespace cv; +using namespace cv::gpu; using namespace std; #if !defined (HAVE_CUDA) @@ -94,219 +94,221 @@ public: /*out*/unsigned int& numDetections) { calculateMemReqsAndAllocate(src.size()); - - NCVMemPtr src_beg; - src_beg.ptr = (void*)src.ptr(); - src_beg.memtype = NCVMemoryTypeDevice; - - NCVMemSegment src_seg; - src_seg.begin = src_beg; - src_seg.size = src.step * src.rows; - - NCVMatrixReuse d_src(src_seg, static_cast(devProp.textureAlignment), src.cols, src.rows, static_cast(src.step), true); - ncvAssertReturn(d_src.isMemReused(), NCV_ALLOCATOR_BAD_REUSE); - - CV_Assert(objects.rows == 1); - - NCVMemPtr objects_beg; - objects_beg.ptr = (void*)objects.ptr(); - objects_beg.memtype = NCVMemoryTypeDevice; - - NCVMemSegment objects_seg; - objects_seg.begin = objects_beg; - objects_seg.size = objects.step * objects.rows; - NCVVectorReuse d_rects(objects_seg, objects.cols); - ncvAssertReturn(d_rects.isMemReused(), NCV_ALLOCATOR_BAD_REUSE); - - NcvSize32u roi; - roi.width = d_src.width(); - roi.height = d_src.height(); - + + NCVMemPtr src_beg; + src_beg.ptr = (void*)src.ptr(); + src_beg.memtype = NCVMemoryTypeDevice; + + NCVMemSegment src_seg; + src_seg.begin = src_beg; + src_seg.size = src.step * src.rows; + + NCVMatrixReuse d_src(src_seg, static_cast(devProp.textureAlignment), src.cols, src.rows, static_cast(src.step), true); + ncvAssertReturn(d_src.isMemReused(), NCV_ALLOCATOR_BAD_REUSE); + + CV_Assert(objects.rows == 1); + + NCVMemPtr objects_beg; + objects_beg.ptr = (void*)objects.ptr(); + objects_beg.memtype = NCVMemoryTypeDevice; + + NCVMemSegment objects_seg; + objects_seg.begin = objects_beg; + objects_seg.size = objects.step * objects.rows; + NCVVectorReuse d_rects(objects_seg, objects.cols); + ncvAssertReturn(d_rects.isMemReused(), NCV_ALLOCATOR_BAD_REUSE); + + NcvSize32u roi; + roi.width = d_src.width(); + roi.height = d_src.height(); + NcvSize32u winMinSize(ncvMinSize.width, ncvMinSize.height); - Ncv32u flags = 0; - flags |= findLargestObject? NCVPipeObjDet_FindLargestObject : 0; - flags |= visualizeInPlace ? NCVPipeObjDet_VisualizeInPlace : 0; - - ncvStat = ncvDetectObjectsMultiScale_device( - d_src, roi, d_rects, numDetections, haar, *h_haarStages, - *d_haarStages, *d_haarNodes, *d_haarFeatures, + Ncv32u flags = 0; + flags |= findLargestObject? NCVPipeObjDet_FindLargestObject : 0; + flags |= visualizeInPlace ? NCVPipeObjDet_VisualizeInPlace : 0; + + ncvStat = ncvDetectObjectsMultiScale_device( + d_src, roi, d_rects, numDetections, haar, *h_haarStages, + *d_haarStages, *d_haarNodes, *d_haarFeatures, winMinSize, - minNeighbors, - scaleStep, 1, - flags, - *gpuAllocator, *cpuAllocator, devProp, 0); - ncvAssertReturnNcvStat(ncvStat); - ncvAssertCUDAReturn(cudaStreamSynchronize(0), NCV_CUDA_ERROR); - - return NCV_SUCCESS; - } - + minNeighbors, + scaleStep, 1, + flags, + *gpuAllocator, *cpuAllocator, devProp, 0); + ncvAssertReturnNcvStat(ncvStat); + ncvAssertCUDAReturn(cudaStreamSynchronize(0), NCV_CUDA_ERROR); + + return NCV_SUCCESS; + } + unsigned int process(const GpuMat& image, GpuMat& objectsBuf, float scaleFactor, int minNeighbors, bool findLargestObject, bool visualizeInPlace, cv::Size minSize, cv::Size maxObjectSize) { CV_Assert( scaleFactor > 1 && image.depth() == CV_8U); - + const int defaultObjSearchNum = 100; if (objectsBuf.empty()) { objectsBuf.create(1, defaultObjSearchNum, DataType::type); } - + cv::Size ncvMinSize = this->getClassifierCvSize(); - + if (ncvMinSize.width < (unsigned)minSize.width && ncvMinSize.height < (unsigned)minSize.height) { ncvMinSize.width = minSize.width; ncvMinSize.height = minSize.height; } - + unsigned int numDetections; ncvSafeCall(this->process(image, objectsBuf, (float)scaleFactor, minNeighbors, findLargestObject, visualizeInPlace, ncvMinSize, numDetections)); - + return numDetections; } cv::Size getClassifierCvSize() const { return cv::Size(haar.ClassifierSize.width, haar.ClassifierSize.height); } - + private: static void NCVDebugOutputHandler(const std::string &msg) { CV_Error(CV_GpuApiCallError, msg.c_str()); } - - NCVStatus load(const string& classifierFile) - { - int devId = cv::gpu::getDevice(); - ncvAssertCUDAReturn(cudaGetDeviceProperties(&devProp, devId), NCV_CUDA_ERROR); - - // Load the classifier from file (assuming its size is about 1 mb) using a simple allocator - gpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeDevice, static_cast(devProp.textureAlignment)); - cpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeHostPinned, static_cast(devProp.textureAlignment)); - - ncvAssertPrintReturn(gpuCascadeAllocator->isInitialized(), "Error creating cascade GPU allocator", NCV_CUDA_ERROR); - ncvAssertPrintReturn(cpuCascadeAllocator->isInitialized(), "Error creating cascade CPU allocator", NCV_CUDA_ERROR); - - Ncv32u haarNumStages, haarNumNodes, haarNumFeatures; - ncvStat = ncvHaarGetClassifierSize(classifierFile, haarNumStages, haarNumNodes, haarNumFeatures); - ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error reading classifier size (check the file)", NCV_FILE_ERROR); - - h_haarStages = new NCVVectorAlloc(*cpuCascadeAllocator, haarNumStages); - h_haarNodes = new NCVVectorAlloc(*cpuCascadeAllocator, haarNumNodes); - h_haarFeatures = new NCVVectorAlloc(*cpuCascadeAllocator, haarNumFeatures); - - ncvAssertPrintReturn(h_haarStages->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR); - ncvAssertPrintReturn(h_haarNodes->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR); - ncvAssertPrintReturn(h_haarFeatures->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR); - - ncvStat = ncvHaarLoadFromFile_host(classifierFile, haar, *h_haarStages, *h_haarNodes, *h_haarFeatures); - ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error loading classifier", NCV_FILE_ERROR); - - d_haarStages = new NCVVectorAlloc(*gpuCascadeAllocator, haarNumStages); - d_haarNodes = new NCVVectorAlloc(*gpuCascadeAllocator, haarNumNodes); - d_haarFeatures = new NCVVectorAlloc(*gpuCascadeAllocator, haarNumFeatures); - - ncvAssertPrintReturn(d_haarStages->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR); - ncvAssertPrintReturn(d_haarNodes->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR); - ncvAssertPrintReturn(d_haarFeatures->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR); - - ncvStat = h_haarStages->copySolid(*d_haarStages, 0); - ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR); - ncvStat = h_haarNodes->copySolid(*d_haarNodes, 0); - ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR); - ncvStat = h_haarFeatures->copySolid(*d_haarFeatures, 0); - ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR); - - return NCV_SUCCESS; - } - - NCVStatus calculateMemReqsAndAllocate(const Size& frameSize) - { - if (lastAllocatedFrameSize == frameSize) - { - return NCV_SUCCESS; - } - - // Calculate memory requirements and create real allocators - NCVMemStackAllocator gpuCounter(static_cast(devProp.textureAlignment)); - NCVMemStackAllocator cpuCounter(static_cast(devProp.textureAlignment)); - - ncvAssertPrintReturn(gpuCounter.isInitialized(), "Error creating GPU memory counter", NCV_CUDA_ERROR); - ncvAssertPrintReturn(cpuCounter.isInitialized(), "Error creating CPU memory counter", NCV_CUDA_ERROR); - - NCVMatrixAlloc d_src(gpuCounter, frameSize.width, frameSize.height); - NCVMatrixAlloc h_src(cpuCounter, frameSize.width, frameSize.height); - - ncvAssertReturn(d_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC); - ncvAssertReturn(h_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC); - - NCVVectorAlloc d_rects(gpuCounter, 100); - ncvAssertReturn(d_rects.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC); - - NcvSize32u roi; - roi.width = d_src.width(); - roi.height = d_src.height(); - Ncv32u numDetections; - ncvStat = ncvDetectObjectsMultiScale_device(d_src, roi, d_rects, numDetections, haar, *h_haarStages, - *d_haarStages, *d_haarNodes, *d_haarFeatures, haar.ClassifierSize, 4, 1.2f, 1, 0, gpuCounter, cpuCounter, devProp, 0); - - ncvAssertReturnNcvStat(ncvStat); - ncvAssertCUDAReturn(cudaStreamSynchronize(0), NCV_CUDA_ERROR); - - gpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeDevice, gpuCounter.maxSize(), static_cast(devProp.textureAlignment)); - cpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeHostPinned, cpuCounter.maxSize(), static_cast(devProp.textureAlignment)); - - ncvAssertPrintReturn(gpuAllocator->isInitialized(), "Error creating GPU memory allocator", NCV_CUDA_ERROR); - ncvAssertPrintReturn(cpuAllocator->isInitialized(), "Error creating CPU memory allocator", NCV_CUDA_ERROR); - return NCV_SUCCESS; - } - - cudaDeviceProp devProp; - NCVStatus ncvStat; - - Ptr gpuCascadeAllocator; - Ptr cpuCascadeAllocator; - - Ptr > h_haarStages; - Ptr > h_haarNodes; - Ptr > h_haarFeatures; - - HaarClassifierCascadeDescriptor haar; - - Ptr > d_haarStages; - Ptr > d_haarNodes; - Ptr > d_haarFeatures; - - Size lastAllocatedFrameSize; - - Ptr gpuAllocator; - Ptr cpuAllocator; + + NCVStatus load(const string& classifierFile) + { + int devId = cv::gpu::getDevice(); + ncvAssertCUDAReturn(cudaGetDeviceProperties(&devProp, devId), NCV_CUDA_ERROR); + + // Load the classifier from file (assuming its size is about 1 mb) using a simple allocator + gpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeDevice, static_cast(devProp.textureAlignment)); + cpuCascadeAllocator = new NCVMemNativeAllocator(NCVMemoryTypeHostPinned, static_cast(devProp.textureAlignment)); + + ncvAssertPrintReturn(gpuCascadeAllocator->isInitialized(), "Error creating cascade GPU allocator", NCV_CUDA_ERROR); + ncvAssertPrintReturn(cpuCascadeAllocator->isInitialized(), "Error creating cascade CPU allocator", NCV_CUDA_ERROR); + + Ncv32u haarNumStages, haarNumNodes, haarNumFeatures; + ncvStat = ncvHaarGetClassifierSize(classifierFile, haarNumStages, haarNumNodes, haarNumFeatures); + ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error reading classifier size (check the file)", NCV_FILE_ERROR); + + h_haarStages = new NCVVectorAlloc(*cpuCascadeAllocator, haarNumStages); + h_haarNodes = new NCVVectorAlloc(*cpuCascadeAllocator, haarNumNodes); + h_haarFeatures = new NCVVectorAlloc(*cpuCascadeAllocator, haarNumFeatures); + + ncvAssertPrintReturn(h_haarStages->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR); + ncvAssertPrintReturn(h_haarNodes->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR); + ncvAssertPrintReturn(h_haarFeatures->isMemAllocated(), "Error in cascade CPU allocator", NCV_CUDA_ERROR); + + ncvStat = ncvHaarLoadFromFile_host(classifierFile, haar, *h_haarStages, *h_haarNodes, *h_haarFeatures); + ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error loading classifier", NCV_FILE_ERROR); + + d_haarStages = new NCVVectorAlloc(*gpuCascadeAllocator, haarNumStages); + d_haarNodes = new NCVVectorAlloc(*gpuCascadeAllocator, haarNumNodes); + d_haarFeatures = new NCVVectorAlloc(*gpuCascadeAllocator, haarNumFeatures); + + ncvAssertPrintReturn(d_haarStages->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR); + ncvAssertPrintReturn(d_haarNodes->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR); + ncvAssertPrintReturn(d_haarFeatures->isMemAllocated(), "Error in cascade GPU allocator", NCV_CUDA_ERROR); + + ncvStat = h_haarStages->copySolid(*d_haarStages, 0); + ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR); + ncvStat = h_haarNodes->copySolid(*d_haarNodes, 0); + ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR); + ncvStat = h_haarFeatures->copySolid(*d_haarFeatures, 0); + ncvAssertPrintReturn(ncvStat == NCV_SUCCESS, "Error copying cascade to GPU", NCV_CUDA_ERROR); + + return NCV_SUCCESS; + } + + NCVStatus calculateMemReqsAndAllocate(const Size& frameSize) + { + if (lastAllocatedFrameSize == frameSize) + { + return NCV_SUCCESS; + } + + // Calculate memory requirements and create real allocators + NCVMemStackAllocator gpuCounter(static_cast(devProp.textureAlignment)); + NCVMemStackAllocator cpuCounter(static_cast(devProp.textureAlignment)); + + ncvAssertPrintReturn(gpuCounter.isInitialized(), "Error creating GPU memory counter", NCV_CUDA_ERROR); + ncvAssertPrintReturn(cpuCounter.isInitialized(), "Error creating CPU memory counter", NCV_CUDA_ERROR); + + NCVMatrixAlloc d_src(gpuCounter, frameSize.width, frameSize.height); + NCVMatrixAlloc h_src(cpuCounter, frameSize.width, frameSize.height); + + ncvAssertReturn(d_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC); + ncvAssertReturn(h_src.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC); + + NCVVectorAlloc d_rects(gpuCounter, 100); + ncvAssertReturn(d_rects.isMemAllocated(), NCV_ALLOCATOR_BAD_ALLOC); + + NcvSize32u roi; + roi.width = d_src.width(); + roi.height = d_src.height(); + Ncv32u numDetections; + ncvStat = ncvDetectObjectsMultiScale_device(d_src, roi, d_rects, numDetections, haar, *h_haarStages, + *d_haarStages, *d_haarNodes, *d_haarFeatures, haar.ClassifierSize, 4, 1.2f, 1, 0, gpuCounter, cpuCounter, devProp, 0); + + ncvAssertReturnNcvStat(ncvStat); + ncvAssertCUDAReturn(cudaStreamSynchronize(0), NCV_CUDA_ERROR); + + gpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeDevice, gpuCounter.maxSize(), static_cast(devProp.textureAlignment)); + cpuAllocator = new NCVMemStackAllocator(NCVMemoryTypeHostPinned, cpuCounter.maxSize(), static_cast(devProp.textureAlignment)); + + ncvAssertPrintReturn(gpuAllocator->isInitialized(), "Error creating GPU memory allocator", NCV_CUDA_ERROR); + ncvAssertPrintReturn(cpuAllocator->isInitialized(), "Error creating CPU memory allocator", NCV_CUDA_ERROR); + + lastAllocatedFrameSize = frameSize; + return NCV_SUCCESS; + } + + cudaDeviceProp devProp; + NCVStatus ncvStat; + + Ptr gpuCascadeAllocator; + Ptr cpuCascadeAllocator; + + Ptr > h_haarStages; + Ptr > h_haarNodes; + Ptr > h_haarFeatures; + + HaarClassifierCascadeDescriptor haar; + + Ptr > d_haarStages; + Ptr > d_haarNodes; + Ptr > d_haarFeatures; + + Size lastAllocatedFrameSize; + + Ptr gpuAllocator; + Ptr cpuAllocator; virtual ~HaarCascade(){} -}; - +}; + cv::Size operator -(const cv::Size& a, const cv::Size& b) { return cv::Size(a.width - b.width, a.height - b.height); } - + cv::Size operator +(const cv::Size& a, const int& i) { return cv::Size(a.width + i, a.height + i); } - + cv::Size operator *(const cv::Size& a, const float& f) { return cv::Size(cvRound(a.width * f), cvRound(a.height * f)); } - + cv::Size operator /(const cv::Size& a, const float& f) -{ +{ return cv::Size(cvRound(a.width / f), cvRound(a.height / f)); } bool operator <=(const cv::Size& a, const cv::Size& b) { return a.width <= b.width && a.height <= b.width; -} - +} + struct PyrLavel { PyrLavel(int _order, float _scale, cv::Size frame, cv::Size window, cv::Size minObjectSize) @@ -669,18 +671,18 @@ cv::gpu::CascadeClassifier_GPU::~CascadeClassifier_GPU() { release(); } void cv::gpu::CascadeClassifier_GPU::release() { if (impl) { delete impl; impl = 0; } } bool cv::gpu::CascadeClassifier_GPU::empty() const { return impl == 0; } - -Size cv::gpu::CascadeClassifier_GPU::getClassifierSize() const -{ - return this->empty() ? Size() : impl->getClassifierCvSize(); -} - -int cv::gpu::CascadeClassifier_GPU::detectMultiScale( const GpuMat& image, GpuMat& objectsBuf, double scaleFactor, int minNeighbors, Size minSize) -{ - CV_Assert( !this->empty()); + +Size cv::gpu::CascadeClassifier_GPU::getClassifierSize() const +{ + return this->empty() ? Size() : impl->getClassifierCvSize(); +} + +int cv::gpu::CascadeClassifier_GPU::detectMultiScale( const GpuMat& image, GpuMat& objectsBuf, double scaleFactor, int minNeighbors, Size minSize) +{ + CV_Assert( !this->empty()); return impl->process(image, objectsBuf, (float)scaleFactor, minNeighbors, findLargestObject, visualizeInPlace, minSize, cv::Size()); } - + int cv::gpu::CascadeClassifier_GPU::detectMultiScale(const GpuMat& image, GpuMat& objectsBuf, Size maxObjectSize, Size minSize, double scaleFactor, int minNeighbors) { CV_Assert( !this->empty()); @@ -695,261 +697,261 @@ bool cv::gpu::CascadeClassifier_GPU::load(const string& filename) std::transform(fext.begin(), fext.end(), fext.begin(), ::tolower); if (fext == "nvbin") - { + { impl = new HaarCascade(); return impl->read(filename); - } - + } + FileStorage fs(filename, FileStorage::READ); - + if (!fs.isOpened()) - { + { impl = new HaarCascade(); return impl->read(filename); - } - + } + const char *GPU_CC_LBP = "LBP"; string featureTypeStr = (string)fs.getFirstTopLevelNode()["featureType"]; if (featureTypeStr == GPU_CC_LBP) impl = new LbpCascade(); else impl = new HaarCascade(); - + impl->read(filename); return !this->empty(); -} - +} + ////////////////////////////////////////////////////////////////////////////////////////////////////// - -struct RectConvert -{ - Rect operator()(const NcvRect32u& nr) const { return Rect(nr.x, nr.y, nr.width, nr.height); } - NcvRect32u operator()(const Rect& nr) const - { - NcvRect32u rect; - rect.x = nr.x; - rect.y = nr.y; - rect.width = nr.width; - rect.height = nr.height; - return rect; - } -}; - -void groupRectangles(std::vector &hypotheses, int groupThreshold, double eps, std::vector *weights) -{ - vector rects(hypotheses.size()); - std::transform(hypotheses.begin(), hypotheses.end(), rects.begin(), RectConvert()); - - if (weights) - { - vector weights_int; - weights_int.assign(weights->begin(), weights->end()); - cv::groupRectangles(rects, weights_int, groupThreshold, eps); - } - else - { - cv::groupRectangles(rects, groupThreshold, eps); - } - std::transform(rects.begin(), rects.end(), hypotheses.begin(), RectConvert()); - hypotheses.resize(rects.size()); -} - -NCVStatus loadFromXML(const std::string &filename, - HaarClassifierCascadeDescriptor &haar, - std::vector &haarStages, - std::vector &haarClassifierNodes, - std::vector &haarFeatures) -{ - NCVStatus ncvStat; - - haar.NumStages = 0; - haar.NumClassifierRootNodes = 0; - haar.NumClassifierTotalNodes = 0; - haar.NumFeatures = 0; - haar.ClassifierSize.width = 0; - haar.ClassifierSize.height = 0; - haar.bHasStumpsOnly = true; - haar.bNeedsTiltedII = false; - Ncv32u curMaxTreeDepth; - - std::vector xmlFileCont; - - std::vector h_TmpClassifierNotRootNodes; - haarStages.resize(0); - haarClassifierNodes.resize(0); - haarFeatures.resize(0); - - Ptr oldCascade = (CvHaarClassifierCascade*)cvLoad(filename.c_str(), 0, 0, 0); - if (oldCascade.empty()) - { - return NCV_HAAR_XML_LOADING_EXCEPTION; - } - - haar.ClassifierSize.width = oldCascade->orig_window_size.width; - haar.ClassifierSize.height = oldCascade->orig_window_size.height; - - int stagesCound = oldCascade->count; - for(int s = 0; s < stagesCound; ++s) // by stages - { - HaarStage64 curStage; - curStage.setStartClassifierRootNodeOffset(static_cast(haarClassifierNodes.size())); - - curStage.setStageThreshold(oldCascade->stage_classifier[s].threshold); - - int treesCount = oldCascade->stage_classifier[s].count; - for(int t = 0; t < treesCount; ++t) // by trees - { - Ncv32u nodeId = 0; - CvHaarClassifier* tree = &oldCascade->stage_classifier[s].classifier[t]; - - int nodesCount = tree->count; - for(int n = 0; n < nodesCount; ++n) //by features - { - CvHaarFeature* feature = &tree->haar_feature[n]; - - HaarClassifierNode128 curNode; - curNode.setThreshold(tree->threshold[n]); - - NcvBool bIsLeftNodeLeaf = false; - NcvBool bIsRightNodeLeaf = false; - - HaarClassifierNodeDescriptor32 nodeLeft; - if ( tree->left[n] <= 0 ) - { - Ncv32f leftVal = tree->alpha[-tree->left[n]]; - ncvStat = nodeLeft.create(leftVal); - ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat); - bIsLeftNodeLeaf = true; - } - else - { - Ncv32u leftNodeOffset = tree->left[n]; - nodeLeft.create((Ncv32u)(h_TmpClassifierNotRootNodes.size() + leftNodeOffset - 1)); - haar.bHasStumpsOnly = false; - } - curNode.setLeftNodeDesc(nodeLeft); - - HaarClassifierNodeDescriptor32 nodeRight; - if ( tree->right[n] <= 0 ) - { - Ncv32f rightVal = tree->alpha[-tree->right[n]]; - ncvStat = nodeRight.create(rightVal); - ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat); - bIsRightNodeLeaf = true; - } - else - { - Ncv32u rightNodeOffset = tree->right[n]; - nodeRight.create((Ncv32u)(h_TmpClassifierNotRootNodes.size() + rightNodeOffset - 1)); - haar.bHasStumpsOnly = false; - } - curNode.setRightNodeDesc(nodeRight); - - Ncv32u tiltedVal = feature->tilted; - haar.bNeedsTiltedII = (tiltedVal != 0); - - Ncv32u featureId = 0; - for(int l = 0; l < CV_HAAR_FEATURE_MAX; ++l) //by rects - { - Ncv32u rectX = feature->rect[l].r.x; - Ncv32u rectY = feature->rect[l].r.y; - Ncv32u rectWidth = feature->rect[l].r.width; - Ncv32u rectHeight = feature->rect[l].r.height; - - Ncv32f rectWeight = feature->rect[l].weight; - - if (rectWeight == 0/* && rectX == 0 &&rectY == 0 && rectWidth == 0 && rectHeight == 0*/) - break; - - HaarFeature64 curFeature; - ncvStat = curFeature.setRect(rectX, rectY, rectWidth, rectHeight, haar.ClassifierSize.width, haar.ClassifierSize.height); - curFeature.setWeight(rectWeight); - ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat); - haarFeatures.push_back(curFeature); - - featureId++; - } - - HaarFeatureDescriptor32 tmpFeatureDesc; - ncvStat = tmpFeatureDesc.create(haar.bNeedsTiltedII, bIsLeftNodeLeaf, bIsRightNodeLeaf, - featureId, static_cast(haarFeatures.size()) - featureId); - ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat); - curNode.setFeatureDesc(tmpFeatureDesc); - - if (!nodeId) - { - //root node - haarClassifierNodes.push_back(curNode); - curMaxTreeDepth = 1; - } - else - { - //other node - h_TmpClassifierNotRootNodes.push_back(curNode); - curMaxTreeDepth++; - } - - nodeId++; - } - } - - curStage.setNumClassifierRootNodes(treesCount); - haarStages.push_back(curStage); - } - - //fill in cascade stats - haar.NumStages = static_cast(haarStages.size()); - haar.NumClassifierRootNodes = static_cast(haarClassifierNodes.size()); - haar.NumClassifierTotalNodes = static_cast(haar.NumClassifierRootNodes + h_TmpClassifierNotRootNodes.size()); - haar.NumFeatures = static_cast(haarFeatures.size()); - - //merge root and leaf nodes in one classifiers array - Ncv32u offsetRoot = static_cast(haarClassifierNodes.size()); - for (Ncv32u i=0; i &hypotheses, int groupThreshold, double eps, std::vector *weights) +{ + vector rects(hypotheses.size()); + std::transform(hypotheses.begin(), hypotheses.end(), rects.begin(), RectConvert()); + + if (weights) + { + vector weights_int; + weights_int.assign(weights->begin(), weights->end()); + cv::groupRectangles(rects, weights_int, groupThreshold, eps); + } + else + { + cv::groupRectangles(rects, groupThreshold, eps); + } + std::transform(rects.begin(), rects.end(), hypotheses.begin(), RectConvert()); + hypotheses.resize(rects.size()); +} + +NCVStatus loadFromXML(const std::string &filename, + HaarClassifierCascadeDescriptor &haar, + std::vector &haarStages, + std::vector &haarClassifierNodes, + std::vector &haarFeatures) +{ + NCVStatus ncvStat; + + haar.NumStages = 0; + haar.NumClassifierRootNodes = 0; + haar.NumClassifierTotalNodes = 0; + haar.NumFeatures = 0; + haar.ClassifierSize.width = 0; + haar.ClassifierSize.height = 0; + haar.bHasStumpsOnly = true; + haar.bNeedsTiltedII = false; + Ncv32u curMaxTreeDepth; + + std::vector xmlFileCont; + + std::vector h_TmpClassifierNotRootNodes; + haarStages.resize(0); + haarClassifierNodes.resize(0); + haarFeatures.resize(0); + + Ptr oldCascade = (CvHaarClassifierCascade*)cvLoad(filename.c_str(), 0, 0, 0); + if (oldCascade.empty()) + { + return NCV_HAAR_XML_LOADING_EXCEPTION; + } + + haar.ClassifierSize.width = oldCascade->orig_window_size.width; + haar.ClassifierSize.height = oldCascade->orig_window_size.height; + + int stagesCound = oldCascade->count; + for(int s = 0; s < stagesCound; ++s) // by stages + { + HaarStage64 curStage; + curStage.setStartClassifierRootNodeOffset(static_cast(haarClassifierNodes.size())); + + curStage.setStageThreshold(oldCascade->stage_classifier[s].threshold); + + int treesCount = oldCascade->stage_classifier[s].count; + for(int t = 0; t < treesCount; ++t) // by trees + { + Ncv32u nodeId = 0; + CvHaarClassifier* tree = &oldCascade->stage_classifier[s].classifier[t]; + + int nodesCount = tree->count; + for(int n = 0; n < nodesCount; ++n) //by features + { + CvHaarFeature* feature = &tree->haar_feature[n]; + + HaarClassifierNode128 curNode; + curNode.setThreshold(tree->threshold[n]); + + NcvBool bIsLeftNodeLeaf = false; + NcvBool bIsRightNodeLeaf = false; + + HaarClassifierNodeDescriptor32 nodeLeft; + if ( tree->left[n] <= 0 ) + { + Ncv32f leftVal = tree->alpha[-tree->left[n]]; + ncvStat = nodeLeft.create(leftVal); + ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat); + bIsLeftNodeLeaf = true; + } + else + { + Ncv32u leftNodeOffset = tree->left[n]; + nodeLeft.create((Ncv32u)(h_TmpClassifierNotRootNodes.size() + leftNodeOffset - 1)); + haar.bHasStumpsOnly = false; + } + curNode.setLeftNodeDesc(nodeLeft); + + HaarClassifierNodeDescriptor32 nodeRight; + if ( tree->right[n] <= 0 ) + { + Ncv32f rightVal = tree->alpha[-tree->right[n]]; + ncvStat = nodeRight.create(rightVal); + ncvAssertReturn(ncvStat == NCV_SUCCESS, ncvStat); + bIsRightNodeLeaf = true; + } + else + { + Ncv32u rightNodeOffset = tree->right[n]; + nodeRight.create((Ncv32u)(h_TmpClassifierNotRootNodes.size() + rightNodeOffset - 1)); + haar.bHasStumpsOnly = false; + } + curNode.setRightNodeDesc(nodeRight); + + Ncv32u tiltedVal = feature->tilted; + haar.bNeedsTiltedII = (tiltedVal != 0); + + Ncv32u featureId = 0; + for(int l = 0; l < CV_HAAR_FEATURE_MAX; ++l) //by rects + { + Ncv32u rectX = feature->rect[l].r.x; + Ncv32u rectY = feature->rect[l].r.y; + Ncv32u rectWidth = feature->rect[l].r.width; + Ncv32u rectHeight = feature->rect[l].r.height; + + Ncv32f rectWeight = feature->rect[l].weight; + + if (rectWeight == 0/* && rectX == 0 &&rectY == 0 && rectWidth == 0 && rectHeight == 0*/) + break; + + HaarFeature64 curFeature; + ncvStat = curFeature.setRect(rectX, rectY, rectWidth, rectHeight, haar.ClassifierSize.width, haar.ClassifierSize.height); + curFeature.setWeight(rectWeight); + ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat); + haarFeatures.push_back(curFeature); + + featureId++; + } + + HaarFeatureDescriptor32 tmpFeatureDesc; + ncvStat = tmpFeatureDesc.create(haar.bNeedsTiltedII, bIsLeftNodeLeaf, bIsRightNodeLeaf, + featureId, static_cast(haarFeatures.size()) - featureId); + ncvAssertReturn(NCV_SUCCESS == ncvStat, ncvStat); + curNode.setFeatureDesc(tmpFeatureDesc); + + if (!nodeId) + { + //root node + haarClassifierNodes.push_back(curNode); + curMaxTreeDepth = 1; + } + else + { + //other node + h_TmpClassifierNotRootNodes.push_back(curNode); + curMaxTreeDepth++; + } + + nodeId++; + } + } + + curStage.setNumClassifierRootNodes(treesCount); + haarStages.push_back(curStage); + } + + //fill in cascade stats + haar.NumStages = static_cast(haarStages.size()); + haar.NumClassifierRootNodes = static_cast(haarClassifierNodes.size()); + haar.NumClassifierTotalNodes = static_cast(haar.NumClassifierRootNodes + h_TmpClassifierNotRootNodes.size()); + haar.NumFeatures = static_cast(haarFeatures.size()); + + //merge root and leaf nodes in one classifiers array + Ncv32u offsetRoot = static_cast(haarClassifierNodes.size()); + for (Ncv32u i=0; i Date: Thu, 2 Aug 2012 16:25:30 +0400 Subject: [PATCH 17/17] parallel version of bilateral filter was implemented using parallel_for_ --- .../include/opencv2/core/parallel_tool.hpp | 108 +++++++ modules/core/src/parallel_tool.cpp | 112 +++++++ modules/core/src/precomp.hpp | 1 + modules/imgproc/perf/perf_bilateral.cpp | 38 +++ modules/imgproc/src/precomp.hpp | 1 + modules/imgproc/src/smooth.cpp | 254 +++++++++------ .../imgproc/test/test_bilateral_filter.cpp | 290 ++++++++++++++++++ 7 files changed, 706 insertions(+), 98 deletions(-) create mode 100644 modules/core/include/opencv2/core/parallel_tool.hpp create mode 100644 modules/core/src/parallel_tool.cpp create mode 100644 modules/imgproc/perf/perf_bilateral.cpp create mode 100644 modules/imgproc/test/test_bilateral_filter.cpp diff --git a/modules/core/include/opencv2/core/parallel_tool.hpp b/modules/core/include/opencv2/core/parallel_tool.hpp new file mode 100644 index 000000000..08258d5c2 --- /dev/null +++ b/modules/core/include/opencv2/core/parallel_tool.hpp @@ -0,0 +1,108 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#ifndef __OPENCV_PARALLEL_TOOL_HPP__ +#define __OPENCV_PARALLEL_TOOL_HPP__ + +#ifdef HAVE_CVCONFIG_H +# include +#endif // HAVE_CVCONFIG_H + +/* + HAVE_TBB - using TBB + HAVE_GCD - using GCD + HAVE_OPENMP - using OpenMP + HAVE_CONCURRENCY - using visual studio 2010 concurrency +*/ + +#ifdef HAVE_TBB +# include "tbb/tbb_stddef.h" +# if TBB_VERSION_MAJOR*100 + TBB_VERSION_MINOR >= 202 +# include "tbb/tbb.h" +# include "tbb/task.h" +# undef min +# undef max +# else +# undef HAVE_TBB +# endif // end TBB version +#endif // HAVE_TBB + +#ifdef __cplusplus + +namespace cv +{ + // a base body class + class CV_EXPORTS ParallelLoopBody + { + public: + virtual void operator() (const Range& range) const = 0; + virtual ~ParallelLoopBody(); + }; + + CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body); + + template inline + CV_EXPORTS void parallel_do_(Iterator first, Iterator last, const Body& body) + { +#ifdef HAVE_TBB + tbb::parallel_do(first, last, body); +#else + for ( ; first != last; ++first) + body(*first); +#endif // HAVE_TBB + } + + template inline + CV_EXPORTS void parallel_reduce_(const Range& range, Body& body) + { +#ifdef HAVE_TBB + tbb::parallel_reduce(tbb::blocked_range(range.start, range.end), body); +#else + body(range); +#endif // end HAVE_TBB + } + +} // namespace cv + +#endif // __cplusplus + +#endif // __OPENCV_PARALLEL_TOOL_HPP__ diff --git a/modules/core/src/parallel_tool.cpp b/modules/core/src/parallel_tool.cpp new file mode 100644 index 000000000..423d4787d --- /dev/null +++ b/modules/core/src/parallel_tool.cpp @@ -0,0 +1,112 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "precomp.hpp" + +#ifdef HAVE_CONCURRENCY +# include +#elif defined HAVE_OPENMP +# include +#elif defined HAVE_GCD +# include +#endif // HAVE_CONCURRENCY + +namespace cv +{ + ParallelLoopBody::~ParallelLoopBody() { } + +#ifdef HAVE_TBB + class TbbProxyLoopBody + { + public: + TbbProxyLoopBody(const ParallelLoopBody& _body) : + body(&_body) + { } + + void operator ()(const tbb::blocked_range& range) const + { + body->operator()(Range(range.begin(), range.end())); + } + + private: + const ParallelLoopBody* body; + }; +#endif // end HAVE_TBB + +#ifdef HAVE_GCD + static + void block_function(void* context, size_t index) + { + ParallelLoopBody* ptr_body = static_cast(context); + ptr_body->operator()(Range(index, index + 1)); + } +#endif // HAVE_GCD + + void parallel_for_(const Range& range, const ParallelLoopBody& body) + { +#ifdef HAVE_TBB + + tbb::parallel_for(tbb::blocked_range(range.start, range.end), TbbProxyLoopBody(body)); + +#elif defined HAVE_CONCURRENCY + + Concurrency::parallel_for(range.start, range.end, body); + +#elif defined HAVE_OPENMP + +#pragma omp parallel for schedule(dynamic) + for (int i = range.start; i < range.end; ++i) + body(Range(i, i + 1)); + +#elif defined (HAVE_GCD) + + dispatch_queue_t concurrent_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); + dispatch_apply_f(range.end - range.start, concurrent_queue, &const_cast(body), block_function); + +#else + + body(range); + +#endif // end HAVE_TBB + } + +} // namespace cv diff --git a/modules/core/src/precomp.hpp b/modules/core/src/precomp.hpp index 81b9d6e80..60429075a 100644 --- a/modules/core/src/precomp.hpp +++ b/modules/core/src/precomp.hpp @@ -50,6 +50,7 @@ #include "opencv2/core/core.hpp" #include "opencv2/core/core_c.h" #include "opencv2/core/internal.hpp" +#include "opencv2/core/parallel_tool.hpp" #include #include diff --git a/modules/imgproc/perf/perf_bilateral.cpp b/modules/imgproc/perf/perf_bilateral.cpp new file mode 100644 index 000000000..85cfc7d0c --- /dev/null +++ b/modules/imgproc/perf/perf_bilateral.cpp @@ -0,0 +1,38 @@ +#include "perf_precomp.hpp" + +using namespace std; +using namespace cv; +using namespace perf; +using namespace testing; +using std::tr1::make_tuple; +using std::tr1::get; + +CV_ENUM(Mat_Type, CV_8UC1, CV_8UC3, CV_32FC1, CV_32FC3) + +typedef TestBaseWithParam< tr1::tuple > TestBilateralFilter; + +PERF_TEST_P( TestBilateralFilter, BilateralFilter, + Combine( + Values( szVGA, sz1080p ), // image size + Values( 3, 5 ), // d + ValuesIn( Mat_Type::all() ) // image type + ) +) +{ + Size sz; + int d, type; + const double sigmaColor = 1., sigmaSpace = 1.; + + sz = get<0>(GetParam()); + d = get<1>(GetParam()); + type = get<2>(GetParam()); + + Mat src(sz, type); + Mat dst(sz, type); + + declare.in(src, WARMUP_RNG).out(dst).time(20); + + TEST_CYCLE() bilateralFilter(src, dst, d, sigmaColor, sigmaSpace, BORDER_DEFAULT); + + SANITY_CHECK(dst); +} diff --git a/modules/imgproc/src/precomp.hpp b/modules/imgproc/src/precomp.hpp index fef5f755b..998008ae2 100644 --- a/modules/imgproc/src/precomp.hpp +++ b/modules/imgproc/src/precomp.hpp @@ -50,6 +50,7 @@ #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/imgproc/imgproc_c.h" #include "opencv2/core/internal.hpp" +#include "opencv2/core/parallel_tool.hpp" #include #include #include diff --git a/modules/imgproc/src/smooth.cpp b/modules/imgproc/src/smooth.cpp index faec530b8..1bc11c7fc 100644 --- a/modules/imgproc/src/smooth.cpp +++ b/modules/imgproc/src/smooth.cpp @@ -1288,48 +1288,119 @@ void cv::medianBlur( InputArray _src0, OutputArray _dst, int ksize ) namespace cv { +class BilateralFilter_8u_Invoker : + public ParallelLoopBody +{ +public: + BilateralFilter_8u_Invoker(const Mat &_src, Mat& _dst, Mat _temp, int _radius, int _maxk, + int* _space_ofs, float *_space_weight, float *_color_weight) : + ParallelLoopBody(), src(_src), dst(_dst), temp(_temp), radius(_radius), + maxk(_maxk), space_ofs(_space_ofs), space_weight(_space_weight), color_weight(_color_weight) + { + } + + virtual void operator() (const Range& range) const + { + int i, j, cn = src.channels(), k; + Size size = src.size(); + + for( i = range.start; i < range.end; i++ ) + { + const uchar* sptr = temp.data + (i+radius)*temp.step + radius*cn; + uchar* dptr = dst.data + i*dst.step; + + if( cn == 1 ) + { + for( j = 0; j < size.width; j++ ) + { + float sum = 0, wsum = 0; + int val0 = sptr[j]; + for( k = 0; k < maxk; k++ ) + { + int val = sptr[j + space_ofs[k]]; + float w = space_weight[k]*color_weight[std::abs(val - val0)]; + sum += val*w; + wsum += w; + } + // overflow is not possible here => there is no need to use CV_CAST_8U + dptr[j] = (uchar)cvRound(sum/wsum); + } + } + else + { + assert( cn == 3 ); + for( j = 0; j < size.width*3; j += 3 ) + { + float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; + int b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; + for( k = 0; k < maxk; k++ ) + { + const uchar* sptr_k = sptr + j + space_ofs[k]; + int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; + float w = space_weight[k]*color_weight[std::abs(b - b0) + + std::abs(g - g0) + std::abs(r - r0)]; + sum_b += b*w; sum_g += g*w; sum_r += r*w; + wsum += w; + } + wsum = 1.f/wsum; + b0 = cvRound(sum_b*wsum); + g0 = cvRound(sum_g*wsum); + r0 = cvRound(sum_r*wsum); + dptr[j] = (uchar)b0; dptr[j+1] = (uchar)g0; dptr[j+2] = (uchar)r0; + } + } + } + } + +private: + const Mat& src; + Mat &dst, temp; + int radius, maxk, * space_ofs; + float *space_weight, *color_weight; +}; + static void bilateralFilter_8u( const Mat& src, Mat& dst, int d, - double sigma_color, double sigma_space, - int borderType ) + double sigma_color, double sigma_space, + int borderType ) { int cn = src.channels(); - int i, j, k, maxk, radius; + int i, j, maxk, radius; Size size = src.size(); - + CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) && - src.type() == dst.type() && src.size() == dst.size() && - src.data != dst.data ); - + src.type() == dst.type() && src.size() == dst.size() && + src.data != dst.data ); + if( sigma_color <= 0 ) sigma_color = 1; if( sigma_space <= 0 ) sigma_space = 1; - + double gauss_color_coeff = -0.5/(sigma_color*sigma_color); double gauss_space_coeff = -0.5/(sigma_space*sigma_space); - + if( d <= 0 ) radius = cvRound(sigma_space*1.5); else radius = d/2; radius = MAX(radius, 1); d = radius*2 + 1; - + Mat temp; copyMakeBorder( src, temp, radius, radius, radius, radius, borderType ); - + vector _color_weight(cn*256); vector _space_weight(d*d); vector _space_ofs(d*d); float* color_weight = &_color_weight[0]; float* space_weight = &_space_weight[0]; int* space_ofs = &_space_ofs[0]; - + // initialize color-related bilateral filter coefficients for( i = 0; i < 256*cn; i++ ) color_weight[i] = (float)std::exp(i*i*gauss_color_coeff); - + // initialize space-related bilateral filter coefficients for( i = -radius, maxk = 0; i <= radius; i++ ) for( j = -radius; j <= radius; j++ ) @@ -1340,55 +1411,89 @@ bilateralFilter_8u( const Mat& src, Mat& dst, int d, space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff); space_ofs[maxk++] = (int)(i*temp.step + j*cn); } + + BilateralFilter_8u_Invoker body(src, dst, temp, radius, maxk, space_ofs, space_weight, color_weight); + parallel_for_(Range(0, size.height), body); +} - for( i = 0; i < size.height; i++ ) + +class BilateralFilter_32f_Invoker : + public ParallelLoopBody +{ +public: + + BilateralFilter_32f_Invoker(int _cn, int _radius, int _maxk, int *_space_ofs, + Mat _temp, Mat *_dest, Size _size, + float _scale_index, float *_space_weight, float *_expLUT) : + ParallelLoopBody(), cn(_cn), radius(_radius), maxk(_maxk), space_ofs(_space_ofs), + temp(_temp), dest(_dest), size(_size), scale_index(_scale_index), space_weight(_space_weight), expLUT(_expLUT) { - const uchar* sptr = temp.data + (i+radius)*temp.step + radius*cn; - uchar* dptr = dst.data + i*dst.step; + } - if( cn == 1 ) + virtual void operator() (const Range& range) const + { + Mat& dst = *dest; + int i, j, k; + + for( i = range.start; i < range.end; i++ ) { - for( j = 0; j < size.width; j++ ) + const float* sptr = (const float*)(temp.data + (i+radius)*temp.step) + radius*cn; + float* dptr = (float*)(dst.data + i*dst.step); + + if( cn == 1 ) { - float sum = 0, wsum = 0; - int val0 = sptr[j]; - for( k = 0; k < maxk; k++ ) + for( j = 0; j < size.width; j++ ) { - int val = sptr[j + space_ofs[k]]; - float w = space_weight[k]*color_weight[std::abs(val - val0)]; - sum += val*w; - wsum += w; + float sum = 0, wsum = 0; + float val0 = sptr[j]; + for( k = 0; k < maxk; k++ ) + { + float val = sptr[j + space_ofs[k]]; + float alpha = (float)(std::abs(val - val0)*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum += val*w; + wsum += w; + } + dptr[j] = (float)(sum/wsum); } - // overflow is not possible here => there is no need to use CV_CAST_8U - dptr[j] = (uchar)cvRound(sum/wsum); } - } - else - { - assert( cn == 3 ); - for( j = 0; j < size.width*3; j += 3 ) + else { - float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; - int b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; - for( k = 0; k < maxk; k++ ) + assert( cn == 3 ); + for( j = 0; j < size.width*3; j += 3 ) { - const uchar* sptr_k = sptr + j + space_ofs[k]; - int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; - float w = space_weight[k]*color_weight[std::abs(b - b0) + - std::abs(g - g0) + std::abs(r - r0)]; - sum_b += b*w; sum_g += g*w; sum_r += r*w; - wsum += w; + float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; + float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; + for( k = 0; k < maxk; k++ ) + { + const float* sptr_k = sptr + j + space_ofs[k]; + float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; + float alpha = (float)((std::abs(b - b0) + + std::abs(g - g0) + std::abs(r - r0))*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum_b += b*w; sum_g += g*w; sum_r += r*w; + wsum += w; + } + wsum = 1.f/wsum; + b0 = sum_b*wsum; + g0 = sum_g*wsum; + r0 = sum_r*wsum; + dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0; } - wsum = 1.f/wsum; - b0 = cvRound(sum_b*wsum); - g0 = cvRound(sum_g*wsum); - r0 = cvRound(sum_r*wsum); - dptr[j] = (uchar)b0; dptr[j+1] = (uchar)g0; dptr[j+2] = (uchar)r0; } } } -} +private: + int cn, radius, maxk, *space_ofs; + Mat temp, *dest; + Size size; + float scale_index, *space_weight, *expLUT; +}; static void bilateralFilter_32f( const Mat& src, Mat& dst, int d, @@ -1396,7 +1501,7 @@ bilateralFilter_32f( const Mat& src, Mat& dst, int d, int borderType ) { int cn = src.channels(); - int i, j, k, maxk, radius; + int i, j, maxk, radius; double minValSrc=-1, maxValSrc=1; const int kExpNumBinsPerChannel = 1 << 12; int kExpNumBins = 0; @@ -1474,57 +1579,10 @@ bilateralFilter_32f( const Mat& src, Mat& dst, int d, space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn); } - for( i = 0; i < size.height; i++ ) - { - const float* sptr = (const float*)(temp.data + (i+radius)*temp.step) + radius*cn; - float* dptr = (float*)(dst.data + i*dst.step); + // parallel_for usage - if( cn == 1 ) - { - for( j = 0; j < size.width; j++ ) - { - float sum = 0, wsum = 0; - float val0 = sptr[j]; - for( k = 0; k < maxk; k++ ) - { - float val = sptr[j + space_ofs[k]]; - float alpha = (float)(std::abs(val - val0)*scale_index); - int idx = cvFloor(alpha); - alpha -= idx; - float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); - sum += val*w; - wsum += w; - } - dptr[j] = (float)(sum/wsum); - } - } - else - { - assert( cn == 3 ); - for( j = 0; j < size.width*3; j += 3 ) - { - float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; - float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; - for( k = 0; k < maxk; k++ ) - { - const float* sptr_k = sptr + j + space_ofs[k]; - float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; - float alpha = (float)((std::abs(b - b0) + - std::abs(g - g0) + std::abs(r - r0))*scale_index); - int idx = cvFloor(alpha); - alpha -= idx; - float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); - sum_b += b*w; sum_g += g*w; sum_r += r*w; - wsum += w; - } - wsum = 1.f/wsum; - b0 = sum_b*wsum; - g0 = sum_g*wsum; - r0 = sum_r*wsum; - dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0; - } - } - } + BilateralFilter_32f_Invoker body(cn, radius, maxk, space_ofs, temp, &dst, size, scale_index, space_weight, expLUT); + parallel_for_(Range(0, size.height), body); } } diff --git a/modules/imgproc/test/test_bilateral_filter.cpp b/modules/imgproc/test/test_bilateral_filter.cpp new file mode 100644 index 000000000..034f9c363 --- /dev/null +++ b/modules/imgproc/test/test_bilateral_filter.cpp @@ -0,0 +1,290 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include "test_precomp.hpp" + +using namespace cv; + +namespace cvtest +{ + class CV_BilateralFilterTest : + public cvtest::BaseTest + { + public: + enum + { + MAX_WIDTH = 1920, MIN_WIDTH = 1, + MAX_HEIGHT = 1080, MIN_HEIGHT = 1 + }; + + CV_BilateralFilterTest(); + ~CV_BilateralFilterTest(); + + protected: + virtual void run_func(); + virtual int prepare_test_case(int test_case_index); + virtual int validate_test_results(int test_case_index); + + private: + void reference_bilateral_filter(const Mat& src, Mat& dst, int d, double sigma_color, + double sigma_space, int borderType = BORDER_DEFAULT); + + int getRandInt(RNG& rng, int min_value, int max_value) const; + + double _sigma_color; + double _sigma_space; + + Mat _src; + Mat _parallel_dst; + int _d; + }; + + CV_BilateralFilterTest::CV_BilateralFilterTest() : + cvtest::BaseTest(), _src(), _parallel_dst(), _d() + { + test_case_count = 1000; + } + + CV_BilateralFilterTest::~CV_BilateralFilterTest() + { + } + + int CV_BilateralFilterTest::getRandInt(RNG& rng, int min_value, int max_value) const + { + double rand_value = rng.uniform(log(min_value), log(max_value + 1)); + return cvRound(exp(rand_value)); + } + + void CV_BilateralFilterTest::reference_bilateral_filter(const Mat &src, Mat &dst, int d, + double sigma_color, double sigma_space, int borderType) + { + int cn = src.channels(); + int i, j, k, maxk, radius; + double minValSrc = -1, maxValSrc = 1; + const int kExpNumBinsPerChannel = 1 << 12; + int kExpNumBins = 0; + float lastExpVal = 1.f; + float len, scale_index; + Size size = src.size(); + + dst.create(size, src.type()); + + CV_Assert( (src.type() == CV_32FC1 || src.type() == CV_32FC3) && + src.type() == dst.type() && src.size() == dst.size() && + src.data != dst.data ); + + if( sigma_color <= 0 ) + sigma_color = 1; + if( sigma_space <= 0 ) + sigma_space = 1; + + double gauss_color_coeff = -0.5/(sigma_color*sigma_color); + double gauss_space_coeff = -0.5/(sigma_space*sigma_space); + + if( d <= 0 ) + radius = cvRound(sigma_space*1.5); + else + radius = d/2; + radius = MAX(radius, 1); + d = radius*2 + 1; + // compute the min/max range for the input image (even if multichannel) + + minMaxLoc( src.reshape(1), &minValSrc, &maxValSrc ); + if(std::abs(minValSrc - maxValSrc) < FLT_EPSILON) + { + src.copyTo(dst); + return; + } + + // temporary copy of the image with borders for easy processing + Mat temp; + copyMakeBorder( src, temp, radius, radius, radius, radius, borderType ); + patchNaNs(temp); + + // allocate lookup tables + vector _space_weight(d*d); + vector _space_ofs(d*d); + float* space_weight = &_space_weight[0]; + int* space_ofs = &_space_ofs[0]; + + // assign a length which is slightly more than needed + len = (float)(maxValSrc - minValSrc) * cn; + kExpNumBins = kExpNumBinsPerChannel * cn; + vector _expLUT(kExpNumBins+2); + float* expLUT = &_expLUT[0]; + + scale_index = kExpNumBins/len; + + // initialize the exp LUT + for( i = 0; i < kExpNumBins+2; i++ ) + { + if( lastExpVal > 0.f ) + { + double val = i / scale_index; + expLUT[i] = (float)std::exp(val * val * gauss_color_coeff); + lastExpVal = expLUT[i]; + } + else + expLUT[i] = 0.f; + } + + // initialize space-related bilateral filter coefficients + for( i = -radius, maxk = 0; i <= radius; i++ ) + for( j = -radius; j <= radius; j++ ) + { + double r = std::sqrt((double)i*i + (double)j*j); + if( r > radius ) + continue; + space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff); + space_ofs[maxk++] = (int)(i*(temp.step/sizeof(float)) + j*cn); + } + + for( i = 0; i < size.height; i++ ) + { + const float* sptr = (const float*)(temp.data + (i+radius)*temp.step) + radius*cn; + float* dptr = (float*)(dst.data + i*dst.step); + + if( cn == 1 ) + { + for( j = 0; j < size.width; j++ ) + { + float sum = 0, wsum = 0; + float val0 = sptr[j]; + for( k = 0; k < maxk; k++ ) + { + float val = sptr[j + space_ofs[k]]; + float alpha = (float)(std::abs(val - val0)*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum += val*w; + wsum += w; + } + dptr[j] = (float)(sum/wsum); + } + } + else + { + assert( cn == 3 ); + for( j = 0; j < size.width*3; j += 3 ) + { + float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0; + float b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2]; + for( k = 0; k < maxk; k++ ) + { + const float* sptr_k = sptr + j + space_ofs[k]; + float b = sptr_k[0], g = sptr_k[1], r = sptr_k[2]; + float alpha = (float)((std::abs(b - b0) + + std::abs(g - g0) + std::abs(r - r0))*scale_index); + int idx = cvFloor(alpha); + alpha -= idx; + float w = space_weight[k]*(expLUT[idx] + alpha*(expLUT[idx+1] - expLUT[idx])); + sum_b += b*w; sum_g += g*w; sum_r += r*w; + wsum += w; + } + wsum = 1.f/wsum; + b0 = sum_b*wsum; + g0 = sum_g*wsum; + r0 = sum_r*wsum; + dptr[j] = b0; dptr[j+1] = g0; dptr[j+2] = r0; + } + } + } + } + + int CV_BilateralFilterTest::prepare_test_case(int /* test_case_index */) + { + const static int types[] = { CV_32FC1, CV_32FC3, CV_8UC1, CV_8UC3 }; + RNG& rng = ts->get_rng(); + Size size(getRandInt(rng, MIN_WIDTH, MAX_WIDTH), getRandInt(rng, MIN_HEIGHT, MAX_HEIGHT)); + int type = types[rng(sizeof(types) / sizeof(types[0]))]; + + _d = rng.uniform(0., 1.) > 0.5 ? 5 : 3; + + _src.create(size, type); + + rng.fill(_src, RNG::UNIFORM, 0, 256); + + _sigma_color = _sigma_space = 1.; + + return 1; + } + + int CV_BilateralFilterTest::validate_test_results(int test_case_index) + { + static const double eps = 1; + + Mat reference_dst, reference_src; + if (_src.depth() == CV_32F) + reference_bilateral_filter(_src, reference_dst, _d, _sigma_color, _sigma_space); + else + { + int type = _src.type(); + _src.convertTo(reference_src, CV_32F); + reference_bilateral_filter(reference_src, reference_dst, _d, _sigma_color, _sigma_space); + reference_dst.convertTo(reference_dst, type); + } + + double e = norm(reference_dst, _parallel_dst); + if (e > eps) + { + ts->printf(cvtest::TS::CONSOLE, "actual error: %g, expected: %g", e, eps); + ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); + } + else + ts->set_failed_test_info(cvtest::TS::OK); + + return BaseTest::validate_test_results(test_case_index); + } + + void CV_BilateralFilterTest::run_func() + { + bilateralFilter(_src, _parallel_dst, _d, _sigma_color, _sigma_space); + } + + TEST(Imgproc_BilateralFilter, accuracy) + { + CV_BilateralFilterTest test; + test.safe_run(); + } + +} // end of namespace cvtest