OpenCV change keypoint or descriptor parameters after creation - opencv

In recent versions, OpenCV allows easy creation of keypoint detectors, descriptors or matchers using the create function, e.g.
cv::Ptr<cv::FeatureDetector> featureDetector = cv::FeatureDetector::create("FAST")
This call does NOT support parameters. E.g. SURF, FAST, etc. all have many parameters.
How can I change them now?
I already figured out parts of it, e.g. I can get the list (list of strings) of parameters via
std::vector<std::string> parameters;
featureDetector->getParams(parameters);
and apparently I need to get somehow to the cv::Algorithm* object to call set(char*, bool/int/float/... value), but I don't know how.

Actually as it turns out, featureDetector already is an Algorithm object, i.e. you can simply set parameters on it directly, e.g.
featureDetector->set("someParam", someValue)
If you want to know about the parameters of a feature detector, you can use this function which prints them for you:
void ClassificationUtilities::printParams( cv::Algorithm* algorithm ) {
std::vector<std::string> parameters;
algorithm->getParams(parameters);
for (int i = 0; i < (int) parameters.size(); i++) {
std::string param = parameters[i];
int type = algorithm->paramType(param);
std::string helpText = algorithm->paramHelp(param);
std::string typeText;
switch (type) {
case cv::Param::BOOLEAN:
typeText = "bool";
break;
case cv::Param::INT:
typeText = "int";
break;
case cv::Param::REAL:
typeText = "real (double)";
break;
case cv::Param::STRING:
typeText = "string";
break;
case cv::Param::MAT:
typeText = "Mat";
break;
case cv::Param::ALGORITHM:
typeText = "Algorithm";
break;
case cv::Param::MAT_VECTOR:
typeText = "Mat vector";
break;
}
std::cout << "Parameter '" << param << "' type=" << typeText << " help=" << helpText << std::endl;
}
}

Related

How best to convert old Dart code that triggers "The non-nullable variable must be assigned" error?

Take the following non-null safe Dart code:
static String appBarShiftTitleString(int fromEpochSeconds) {
String monthWord;
String dayWord;
DateTime dt = DateTime.fromMillisecondsSinceEpoch(fromEpochSeconds * 1000);
switch (dt.month) {
case 1:
monthWord = "Jan";
break;
case 2:
monthWord = "Feb";
break;
case 3:
monthWord = "Mar";
break;
case 4:
monthWord = "Apr";
break;
case 5:
monthWord = "May";
break;
case 6:
monthWord = "Jun";
break;
case 7:
monthWord = "Jul";
break;
case 8:
monthWord = "Aug";
break;
case 9:
monthWord = "Sep";
break;
case 10:
monthWord = "Oct";
break;
case 11:
monthWord = "Nov";
break;
case 12:
monthWord = "Dec";
break;
}
switch (dt.weekday) {
case 1:
dayWord = "Mon";
break;
case 2:
dayWord = "Tue";
break;
case 3:
dayWord = "Wed";
break;
case 4:
dayWord = "Thu";
break;
case 5:
dayWord = "Fri";
break;
case 6:
dayWord = "Sat";
break;
case 7:
dayWord = "Sun";
break;
}
return dayWord + ' ' + monthWord + ' ' + dt.day.toString();
}
Android Studio is saying, "The non-nullable local variable 'dayWord' must be assigned before it can be used."
I understand the error and have discovered that I can simply modify the first two lines of the method like this:
String monthWord = "error!";
String dayWord = "error!";
This way, I satisfy the language rules, and it will be plainly obvious if we reach what ought to be an impossible situation of the variable not having been assigned.
This seems hacky though... so in these types of scenarios, what is the elegant and proper way to convert this code to null safety, and if there are multiple ways, then what are the pros and cons?
In general, you have a few options:
1. Initialize the variable to some non-null sentinel value and assert later:
String monthWord = '';
// ...
switch (dt.month) {
// ...
}
assert(monthWord.isNotEmpty);
This will cause debug builds to throw AssertionError at runtime if you neglect to handle a case for it in the switch.
2. Make the variable nullable and use the null assertion operator:
String? monthWord;
// ...
switch (dt.month) {
// ...
}
monthWord!;
// Since `monthWord` is a local variable, it will now be promoted to a
// non-nullable `String` type.
This will throw a TypeError in all build types if you neglect to set the variable to a non-null value.
3. Make the variable late
Declaring variables as late states that you promise that the variables will be initialized before they are ever read. The compiler will generate runtime checks that verify that the variable is initialized when you try to access it. This will throw a LateInitializationError in all build types if you neglect to set the variable.
4. Add a default case that throws
If all of your cases set a local variable, adding a default case that throws allows the compiler to deduce that that variable must always be set if code after the switch statement is reached:
String monthWord; // No explicit initialization required!
// ...
switch (dt.month) {
case 1:
monthWord = "Jan";
break;
// ... etc. ...
default:
throw AssertionError('Unhandled case: ${dt.month}');
}
// The compiler now can deduce that `monthWord` is guaranteed to be
// initialized.
(Note that you should not add a default case for this purpose if you're using a switch statement on an enum type. For enums, the compiler and analyzer can determine if your cases are exhaustive and will generate analysis warnings if you accidentally omit any cases.)
As for which approach to use, it's mostly a matter of preference. They're all mostly equivalent in that they'll result in runtime errors. I personally would choose #1 (assert) or #4 (default case) to avoid unnecessary checks in release builds.
In your particular example, I also would just use DateTime.month and DateTime.day as indices into Lists of the month and day names respectively:
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
assert(months.length == 12);
assert(days.length == 7);
var monthWord = months[dt.month - 1];
var dayWord = days [dt.day - 1];

What is the "*all* format in lua file:read() means?

I maintain some old code written in LUA, there are some snippet I could not understand,
local f = io.open("someFile.lua", "r");
local szFileContent = "return {};";
if f then
szFileContent = f:read("*all");
f:close();
end
The format used in read function is something weird, I see the format *a, and *l in lua51 manual https://www.lua.org/manual/5.1/manual.html#pdf-file:read,
but not the *all format
in the function read from liolib.c only the first two ('*' and 'a') characters are checked, the rest of the string is ignored:
// ...
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f);
break;
case 'a': /* file */
read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, "invalid format");
//...

Memory allocation and delete in a class

Having trouble with memory allocation and pointers
I'm having trouble with pointers and dynamic memory. I made a class FileReader that read from a file formated like this.
FirstName,LastName,Year,GPA
String,String,String,Integer
Chris,Knight,Fr,3.8
Mitch,Taylor,Jr,3.5
The first line, I stored it in a vector called Names
and 2nd line in vector called Types.
I also made a vector that holds void pointers since it will hold arbitrary types
My question is, how can I free up those memory in the heap?
#ifndef RECORD_H
#define RECORD_H
class Record{
private:
//POINTER VARIABLES
int *intPtr;
double *doublePtr;
vector<string*> stringPtrList;
//NAMES,TYPES, AND VALUES
vector<string> Names;
vector<string> Types;
vector<void*> Values;
public:
Record(vector<string> _names, vector<string> _types, vector<string>_values){
Names = _names;
Types = _types;
//ALOCATING MEMORY
for (unsigned i = 0; i < Types.size(); i++){
string *stringPtr = new string;
stringPtrList.push_back(stringPtr);
}
for (unsigned int i = 0; i < Types.size(); i++){
if (Types[i] == "Integer"){
intPtr = new int;
*intPtr = stoi(_values[i]);
Values.push_back((void*)intPtr);
}
else if (Types[i] == "Double"){
doublePtr = new double;
*doublePtr = stod(_values[i]);
Values.push_back((void*)doublePtr);
}
else if (Types[i] == "String"){
*stringPtrList[i] = _values[i];
Values.push_back((void*)stringPtrList[i]);
}
else{
cout << "No match Type" << endl;
}
}
}
Record(const Record &r){
int *intPtr = new int;
intPtr = r.intPtr;
double *doublePtr = new double;
doublePtr = r.doublePtr;
for (int i = 0; i < r.stringPtrList.size(); i++){
stringPtrList[i] = new string;
stringPtrList[i] = r.stringPtrList[i];
}
}
~Record(){
delete intPtr, doublePtr;
for (int i = 0; i < Types.size(); i++){
delete stringPtrList[i];
}
cout << "Pointer are deleted" << endl;
}
friend ostream&operator <<(ostream &os, const Record &r){
for (unsigned int i = 0; i < r.Types.size(); i++){
if (r.Types[i] == "Integer"){
os << "Integer: " << *(int*)r.Values[i] << endl;
}
else if (r.Types[i] == "String"){
os << "String" << *static_cast<string*>(r.Values[i]) << endl;
}
else if (r.Types[i] == "Double"){
os << "Double" << *(double*)r.Values[i] << endl;
}
else{
cout << "Fatal Error!" << endl;
}
}
cin.get();
return os;
}
};
#endif
GPA has to be a float, not an int. 3.5 can not be an int.
This sounds like homework question. Even if it isn't, it sounds like you are over-complicating things. Just use a list (vector) of structs.
If you really have to be able to handle any type, just use a value-pair type of stuct, something along the lines of:
struct Record
{
string value;
VAR_TYPE type; //this is some enum you defined.
}
Keep a list of columns with types and column index, so easily process each record as you read it.
Since you know the type of each record, you can cast it to that when you are actually going to use it.
It's much cleaner that way, no need for dynamic allocation (which is slow) and messing with void pointers.

Z3 - How to extract variables from a given formula?

I'm using Z3 C++ API (Version 4.3.1) and I want to extract variables of a formula (An object of type expr). I've found a similar question but it is in Z3py. I am wonder if there is a method in Z3 C/C++ API to extract variables from expr object. Thanks!
For example (some details omitted):
expr fs = implies(x + y == 0, z * x < 15);
std::vector<expr> varlist = get_vars(fs);
Then varlist should contain x,y,z.
The C++ example in the distribution (examples/c++/example.cpp) shows a sample visitor pattern.
It is very simplistic, but will give the idea.
I repeat it here below:
void visit(expr const & e) {
if (e.is_app()) {
unsigned num = e.num_args();
for (unsigned i = 0; i < num; i++) {
visit(e.arg(i));
}
// do something
// Example: print the visited expression
func_decl f = e.decl();
std::cout << "application of " << f.name() << ": " << e << "\n";
}
else if (e.is_quantifier()) {
visit(e.body());
// do something
}
else {
assert(e.is_var());
// do something
}
}
The visitor function can be improved by using
a cache of previously visited expressions because in general Z3 uses shared sub-expressions.
This is similar to the Python example.
Hope this helps

Get Call logs Blackberry

What i want
Hi, I am new to BB development and want to know how can i get all call logs list with attributes like time, number etc programmatically ??
What i Read
i have read this Link but not getting the way to implement.
Also there is not good support like android or iOS for blackberry.
Kindly suggest me with some code snippet.
Thanks
I assume you really do want Java (BBOS) code.
In my opinion, the link you referenced provides sufficient information to code something, but since you seem to need more, I hope this helps:
PhoneLogs _logs = PhoneLogs.getInstance();
int numberOfCalls = _logs.numberOfCalls(PhoneLogs.FOLDER_NORMAL_CALLS);
System.out.println("Number of calls: " + Integer.toString(numberOfCalls));
for ( int i = 0; i < numberOfCalls; i++ ) {
PhoneCallLog phoneLog = (PhoneCallLog)_logs.callAt(i,PhoneLogs.FOLDER_NORMAL_CALLS);
int callType = phoneLog.getType();
String callTypeString = "";
switch (callType) {
case PhoneCallLog.TYPE_MISSED_CALL_OPENED:
case PhoneCallLog.TYPE_MISSED_CALL_UNOPENED:
callTypeString = "Missed";
break;
case PhoneCallLog.TYPE_PLACED_CALL:
callTypeString = "Placed";
break;
case PhoneCallLog.TYPE_RECEIVED_CALL:
callTypeString = "Received";
break;
default:
callTypeString = "Unknown";
break;
}
PhoneCallLogID participant = phoneLog.getParticipant();
System.out.println("Call: " + Integer.toString(i) + " " + callTypeString + " " + participant.getAddressBookFormattedNumber());
}
Sample output (from debug log):
Number of calls: 1
Call: 0 Placed 1 (234) 534-5343 5555

Resources