Created
January 25, 2018 10:48
-
-
Save Pzixel/1fd6afc1cbb5e9473f75fe1541f17ecc to your computer and use it in GitHub Desktop.
Rust OpenCV interop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<typename T> | |
struct CResult | |
{ | |
T value; | |
const char* error; | |
static CResult<T> FromFunction(std::function<T()> function) | |
{ | |
CResult<T> result = {}; | |
try | |
{ | |
result.value = function(); | |
} | |
catch( cv::Exception& e ) | |
{ | |
const char* err_msg = e.what(); | |
auto len = std::strlen(err_msg); | |
auto retained_err = new char[len + 1]; | |
std::strcpy(retained_err, err_msg); | |
result.error = retained_err; | |
} | |
return result; | |
} | |
}; | |
EXTERN_C_BEGIN | |
void c_drop(void* value) | |
{ | |
free(value); | |
value = nullptr; | |
} | |
CResult<double> cv_compare_hist(CvMatrix* first_image, CvMatrix* second_image, int method) { | |
cv::Mat* first_mat = reinterpret_cast<cv::Mat*>(first_image); | |
cv::Mat* second_mat = reinterpret_cast<cv::Mat*>(second_image); | |
auto result = CResult<double>::FromFunction([first_mat, second_mat, method](){ | |
return cv::compareHist(*first_mat, *second_mat, method); | |
}); | |
return result; | |
} | |
EXTERN_C_END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extern "C" { | |
fn c_drop(value: *mut c_void); | |
} | |
#[repr(C)] | |
struct CResult<T: Copy> { | |
value: T, | |
error: *const c_char | |
} | |
impl<T: Copy> Into<Result<T, Cow<'static, str>>> for CResult<T> { | |
fn into(self) -> Result<T, Cow<'static, str>> { | |
if self.error.is_null() { | |
Ok(self.value) | |
} | |
else { | |
unsafe { | |
let c_str = std::ffi::CStr::from_ptr(self.error); | |
let err = match c_str.to_str() { | |
Ok(message) => message.into(), | |
_ => "Unknown error".into() | |
}; | |
Err(err) | |
} | |
} | |
} | |
} | |
impl<T: Copy> Drop for CResult<T> { | |
fn drop(&mut self) { | |
if !self.error.is_null() { | |
unsafe { c_drop(self.error as *mut c_void)} | |
} | |
} | |
} | |
struct Cv {} | |
impl Cv { | |
/// Compares two histograms. | |
/// The function compare two histograms using the specified method. | |
/// The function returns d(first_image, second_image). | |
/// While the function works well with 1-, 2-, 3-dimensional dense histograms, it may not be | |
/// suitable for high-dimensional sparse histograms. | |
/// In such histograms, because of aliasing and sampling problems, | |
/// the coordinates of non-zero histogram bins can slightly shift. | |
/// To compare such histograms or more general sparse configurations of weighted points, | |
/// consider using the cv::EMD function. | |
pub fn compare_hist(first_image: &Mat, second_image: &Mat, method: HistogramComparisionMethod) -> Result<f64, Cow<'static, str>> { | |
let method: c_int = method.to_i64().unwrap() as i32; | |
let result = unsafe { | |
cv_compare_hist(first_image.inner, second_image.inner, method) | |
}; | |
result.into() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment