opencv face recognition LBPH issue - opencv

I have been struggling for two day to find an appropriate way of initializing PtrOfLBPHFaceRecognizer in rust using opencv.
let mut void_pointer = libc::malloc(mem::size_of::<c_void>() as libc::size_t) as *mut c_void;
if void_pointer.is_null() {
panic!("failed to allocate memory");
}
let mut model = PtrOfLBPHFaceRecognizer::from_raw(void_pointer);
let ptr = PtrOfLBPHFaceRecognizer::init(model);
let mut model = PtrOfLBPHFaceRecognizer::deref_mut(ptr);
model.train(&images,&labels);
result is panic with invalid memory reference.
any ideas are appreciated.

You can do this by calling the create method. The default parameters used in C++ to initialize it are also described in the docs.
use opencv::face::prelude::*;
// According to docs, these values are the defaults used in C++
let mut model: PtrOfLBPHFaceRecognizer = <dyn LBPHFaceRecognizer>::create(1, 8, 8, 8, DBL_MAX).unwrap();

Related

Why does the raw parts not correspond to either endianness?

I'm trying to optimize as much as possible an operation done on slices of u32 from arrays of u8. As such, I'm testing different options (for loops, iterators, using ByteOrder crate, etc.)
As part of these tests, I also wanted to check out if I could improve it using from_raw_parts standard function.
Here is my code:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = &random_bytes as *const _ as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
I would've expected at least one one of the two Little or Big endian to be equal to the first print, but instead this does not seem to be the case, e.g. an example output
[d951db30]
143600ff
ff003614
[ff, 0, 36, 14]
What am I doing wrong?
The problem is here:
let view = &random_bytes as *const _ as *const u32;
A slice is a 2-machine-word struct that contains the pointer to data and the element count as members.
By doing &random_bytes, you are taking a reference to this slice structure (which itself contains a pointer and length), not acquiring the underlying pointer.
Slices have an as_ptr method that returns the pointer to data itself. When you use it, your code functions correctly:
use byteorder::{ByteOrder, BigEndian, LittleEndian};
use std::io::Read;
fn main(){
let random_bytes = (0..4).map(|_| { rand::random::<u8>() }).collect::<Vec<u8>>();
let random_bytes = random_bytes.as_slice();
let view = random_bytes.as_ptr() as *const u32;
let slice: &[u32] = unsafe { std::slice::from_raw_parts(view, 1) };
println!("{:x?}", slice);
println!("{:x?}", LittleEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", BigEndian::read_u32(&random_bytes[0..4]));
println!("{:x?}", &random_bytes[0..4]);
}
Output in playground:
[684a2f5b]
684a2f5b
5b2f4a68
[5b, 2f, 4a, 68]

How to pass the same mutable Peekable to different functions in Rust

I want to write a parser.
It seems practical to me to have a mutable Iterator that I can pass around to different parser functions.
I've tried to illustrated a simplified approach, which compiles but is not ideal yet.
fn main() {
let tokens = vec!["fIrSt".to_string(), "SeConD".to_string(), "tHiRd".to_string(), "FoUrTh".to_string()];
let parsed = parse_input(tokens);
println!("{}", parsed);
}
fn parse_input(tokens: Vec<String>) -> String {
let mut tokens_iter = tokens.iter();
let upps = parse_upper(&mut tokens_iter);
let lowers = parse_lower(&mut tokens_iter);
upps + &lowers
}
fn parse_upper(tokens_iter: &mut Iterator<Item=&String>) -> String {
let mut result = String::new();
let token_1 = tokens_iter.next().unwrap().to_uppercase();
let token_2 = tokens_iter.next().unwrap().to_uppercase();
result.push_str(&token_1);
result.push_str(&token_2);
result
}
fn parse_lower(tokens_iter: &mut Iterator<Item=&String>) -> String {
let mut result = String::new();
let token_1 = tokens_iter.next().unwrap().to_lowercase();
let token_2 = tokens_iter.next().unwrap().to_lowercase();
result.push_str(&token_1);
result.push_str(&token_2);
result
}
How the example works:
Let's say I have some input, that has already been tokenized. Here it is represented by the tokens vector (Vec<String>).
Inside the outer parse_input function, the Vec gets transformed into an Iterator and then passed into different, specific parser functions. Here: parse_upper and parse_lower. In real life those could be "parse_if_statement" or "parse_while_loop" but which part of the Iterator gets worked on is not relevant for the question.
What is relevant is, that every call to next advances the cursor on the Iterator. So that every function consumes the pieces it needs.
This example compiles and gives the output: FIRSTSECONDthirdfourth
I would like to be able to peek() into the Iterator, before I pass it to a function. This is necessary to determine which function should actually be called. But everything I have tried with using a Peekable instead of an Iterator resulted in total lifetime and borrow chaos.
Any suggestions on how to pass a Peekable instead of an Iterator in this case?
Maybe using a Peekable as function parameter is a bad idea in the first place. Or maybe my Iterator approach is already wrong. All suggestions/hints are welcome.

Converting C pointers to Swift 3

I have the code:
let data = Data(bytes: UnsafePointer<UInt8>(audioBuffer.mData), count: Int(bufferSize))
and
let u16 = UnsafePointer<Int32>(audioBuffer.mData).pointee
Both of which work in Swift 2.3 but not in Swift 3. How do I convert them so they act equivalently? (and why?)
To read 16-bit audio samples from Audio Unit callback buffers in Swift 3, I use:
let bufferPointer = UnsafeMutableRawPointer(mBuffers.mData)
if var bptr = bufferPointer {
for i in 0..<(Int(frameCount)) {
let oneSampleI16 = bptr.assumingMemoryBound(to: Int16.self).pointee
// do something with the audio sample
bptr += 1
}
}
The rest of the Audio Session and Audio Unit code is in this gist: https://gist.github.com/hotpaw2/630a466cc830e3d129b9
I can't say I understand this well, nor have I read the document, but it looks like swift3 pointer casts are scoped to avoid or limit aliasing, so you can't (easily) have two different views of the same piece of memory, or at least not for very long. This means you must either copy the cast data out or do whatever you need to do within a cast callback.
Why eliminate aliasing? I guess it makes for happier compilers.
For Data:
// [NS]Data. probably copying the data
Data(bytes: audioBuffer.mData!, count: Int(audioBuffer.mDataByteSize))
For numeric arrays:
// cast the data to Int32s & (optionally) copy the data out
let umpInt32 = audioBuffer.mData!.assumingMemoryBound(to: Int32.self)
let frameCount = Int(audioBuffer.mDataByteSize/4)
var u32 = [Int32](repeating: 0, count: frameCount)
// copy data from buffer
u32.withUnsafeMutableBufferPointer {
$0.baseAddress!.initialize(from: umpInt32, count: frameCount)
}
p.s. there's some confusion in your code. is u16 supposed to be an array of Int32s? Or UInt16s? Or something else?
Check the latest reference of Data.init(bytes:count:).
The type of the parameter bytes is UnsafeRawPointer, which accepts UnsafeMutableRawPointer. And the type of AudioBuffer.mData is UnsafeMutableRawPointer?. You have no need to convert using initializer.
let data = Data(bytes: audioBuffer.mData!, count: Int(bufferSize))
(You just need to explicitly unwrap mData, as it is imported as nullable type, UnsafeMutableRawPointer?, but you need to pass non-nil UnsafeRawPointer (or UnsafeMutableRawPointer).
The second example, you'd better check what sort of methods are available for UnsafeMutableRawPointer. You can find load(fromByteOffset:as:) method, and can use it like this.
let i32 = audioBuffer.mData!.load(as: Int32.self)
`load(

How to build WriteBuf from array

I am serializing two values in to an array and I am trying to go through a WriteBuf but I am getting the error that
error: the trait `std::io::Write` is not implemented for the type `[_; 12]`
error: type `std::io::buffered::BufWriter<&mut [_; 12]>` does not implement any method in scope named `write_be_u32`
error: type `std::io::buffered::BufWriter<&mut [_; 12]>` does not implement any method in scope named `write_be_f64`
Here is the minimum code to generate this error:
use std::io::{ BufWriter, Write };
fn main(){
let packed_data = [0; 12];
let timestamp : u32 = 100;
let value : f64 = 9.9;
let writer = BufWriter::new(&mut packed_data);
writer.write_be_u32(timestamp);
writer.write_be_f64(value);
println!("Packed data looks like {:?}", packed_data);
}
Am I no borrowing the slice correctly? Am I note using the proper module to define the Write trait for my buffer?
Here is a playpen for this code: http://is.gd/ol8qND
I see a few potential problems with your code:
packed_data isn't mutable.
You use packed_data at the end of main while writer holds a mutable reference to it.
I don't think that either of those things are causing the error. I did however find something that works:
use std::io::{ BufWriter, Write };
fn main() {
let mut packed_data = [0; 12];
{
let packed_data_ref: &mut [u8] = &mut packed_data;
let mut writer = BufWriter::new(packed_data_ref);
writer.write(&[1, 2, 3, 4]).unwrap();
} // `writer` gets deallocated and releases the mutable reference
println!("Packed data looks like {:?}", packed_data);
}
[playpen]
So I guess the issue is that you need a &[u8] rather than a &[u8; 12]. I have no idea why. I hope this at least helps though.

F# lazy eval from stream reader?

I'm running into a bug in my code that makes me think that I don't really understand some of the details about F# and lazy evaluation. I know that F# evaluates eagerly and therefore am somewhat perplexed by the following function:
// Open a file, then read from it. Close the file. return the data.
let getStringFromFile =
File.OpenRead("c:\\eo\\raw.txt")
|> fun s -> let r = new StreamReader(s)
let data = r.ReadToEnd
r.Close()
s.Close()
data
When I call this in FSI:
> let d = getStringFromFile();;
System.ObjectDisposedException: Cannot read from a closed TextReader.
at System.IO.__Error.ReaderClosed()
at System.IO.StreamReader.ReadToEnd()
at <StartupCode$FSI_0134>.$FSI_0134.main#()
Stopped due to error
This makes me think that getStringFromFile is being evaluated lazily--so I'm totally confused. I'm not getting something about how F# evaluates functions.
For a quick explanation of what's happening, lets start here:
let getStringFromFile =
File.OpenRead("c:\\eo\\raw.txt")
|> fun s -> let r = new StreamReader(s)
let data = r.ReadToEnd
r.Close()
s.Close()
data
You can re-write the first two lines of your function as:
let s = File.OpenRead(#"c:\eo\raw.txt")
Next, you've omitted the parentheses on this method:
let data = r.ReadToEnd
r.Close()
s.Close()
data
As a result, data has the type unit -> string. When you return this value from your function, the entire result is unit -> string. But look what happens in between assigning your variable and returning it: you closed you streams.
End result, when a user calls the function, the streams are already closed, resulting in the error you're seeing above.
And don't forget to dispose your objects by declaring use whatever = ... instead of let whatever = ....
With that in mind, here's a fix:
let getStringFromFile() =
use s = File.OpenRead(#"c:\eo\raw.txt")
use r = new StreamReader(s)
r.ReadToEnd()
You don't read from your file. You bind method ReadToEnd of your instance of StreamReader to the value data and then call it when you call getStringFromFile(). The problem is that the stream is closed at this moment.
I think you have missed the parentheses and here's the correct version:
// Open a file, then read from it. Close the file. return the data.
let getStringFromFile =
File.OpenRead("c:\\eo\\raw.txt")
|> fun s -> let r = new StreamReader(s)
let data = r.ReadToEnd()
r.Close()
s.Close()
data

Resources