Advanced Programming with Modern C++ 23 for Image Processing
make industrial process scale-ups successful
#c++23 #optimization #imageprocessing #deeplearning #AI #IoT
You need latest version of C++ compiler in order to use C++ 20 standard. GCC>12 or CLang>13. CUDA 11 support C++17 by nvcc; Cmake.
mind map
call by value: on stack
void f(int a) { a++; } //a in main not change
call by reference:
void f(int *p); // f(&i);
void f(int &i);// f(i)
void func(const std::string & s) { s.c_str() } // func(s);
struct default is public (use when we have only data members) and class default is private (when also have function members) .
function's signature // int getvalue() const;
// ! this is a very critical comment
// * this is a highlighted comment
// TODO: this is a TODO comment
// ? this is a question comment
flexible, maintainable, extensible
gang of four "design patterns: elements of reusable object oriented software"
23 patterns
creational (5) : object instantiation
factory method
composition: property referenced by another class
inheritance: class extends another class
abstract factory
builder : complex
prototype: clone
singleton: only one instance
structural : class relationships and hierarchies; class pattern: is; structural object patterns: has
adapter
bridge
composite
decorator
facde
flyweight
proxy
behavioral (12): object intercommunication :
chain of responsibility
password check
command
one button for all command
mediator
reduce dependency : married -> spouse name -> ....
observer
std::vector<Subscriber*> subscribers;
this->subscribers.push_back(subscriber);
void unsubscribe(Subscriber *subscriber) override {
subscribers.erase(std::remove_if(subscribers.begin(),subscribers.end(),
[subscriber](Subscriber *s){{return s->getName() ==
subscriber->getName(); }), subscribers.end());
interpreter
1+(2+3)
state
order
strategy
template method
visitor
iterator pattern
memento
undo
null-object
default
UML: unified modeling language
abstract and concrete classes
int x=5;
size_t y=sizeof x; or sizeof(int)
printf("sizeof x is %zd\n",y*8); //change bit to byte
func(){ static int i=5; }// it will change ++ // it will be on static storage not stack
void (*pfunc)()=func;
(*pfunc)();
#include <cstdio>
#include <cstdarg> // variadic argument
double average(const int count, ...) { va_list ap; va_start(ap,count); va_arg(ap,double); va_end(ap); }
template <typename T>
larger executables
confusing error messages
longer compile times
#include<cerrno>
perror("");//
v.begin(); v.end(); v.size(); v.back(); v[5]; v.at(5)
string: s.size(); s.length(); s.find();
std::hex,showbase, oct, fixed, scientific,setprecision(3), floatfield,setw, setfill('-'); std::cin.getline(buf,sizeof(buf));
#include<exception> try { ; } catch (std::exception & e) { e.what() }
class1 * o1= new(nothrow) c1[5]; if (o1==nullptr){}; delete [] o1;
if we don't want to create base class we can put constructor in the private part classname(){}
then use constructor in the protected: classname( ): _name(value) {}
using friend class nameofsubclass; to use private functions ; friend class base;
virtual : maybe overloaded and maybe write in subclass; we need ~
#include <memory>
std::unique_ptr<struct> a(new struct());
auto b=std::make_unique<struct>();
a.reset(new structure()); // delete
auto c=std::move(b); // b is null
c.release();
auto a=std::make_shared<struct>();
auto w1=std::weak_ptr(struct>();
T & x => lvalie reference
T && y => rvalue reference
rule of five (if you define any of these functions you need to define all)
~class();
class(class &);
class(class &&);
class & operator = (class &);
class & operator = (class &&);
[]()->char{}
auto fp=[]<typename T>(const T & n)-> T {return n*5; };
#define MAX(a,b) (a>b ? a:b)
constexpr int ONE =1;
unit tests
virtual Class *clone()= 0 ;
template<auto n>
struct B { /* ... */ };
Module Interface Unit : *.cppm
Module Implementation Unit: *.cpp
Important commands
Compile CUDA for Jetson Nano (JetPack 4.5, CUDA 10.2)
nvcc -std=c++14 -arch=sm_62 -o main.run main.cu
compile c++ 20; based on GCC 12, CLang 13
clang++ -std=c++2a -c helloworld.cpp -Xclang -emit-module-interface -o helloworld.pcm
clang++ -std=c++2a -stdlib=libc++ -fimplicit-modules -fimplicit-module-maps -fprebuilt-module-path=. main.cpp helloworld.cpp
commands
echo "export PATH=.:"$PATH"" >> ~/.bashrc
source ~/.bashrc
htop
ulimit -a
git submodule add (githuburl external/glfw)
Tools
brew install --HEAD LouisBrunner/valgrind/valgrind
valgrind ./a.out
CppCon 2016: John Lakos "Advanced Levelization Techniques (part 1 of 3)
Large Scale C++ software design
retain control of your dependency graph
keep concerns separated
make modules reusable in other contexts at minimal cost
appendix
C++ design patterns: factory method
class c1
{
public:
void c1_test()
{
cout << "main class" << endl;
}
};
class c2:public c1
{
public:
c2()
{
cout << "c2" << endl;
}
};
class c3 :public c1
{
public:
c3()
{
cout << "c3" << endl;
}
};
class factory
{
private:
c1 * _c1;
public:
c1 * function_factory(int i)
{
switch (i)
{
case 1:
return new c2;
break;
case 2:
return new c3;
break;
}
}
};
int main()
{
factory f;
c1* c;
c = f.function_factory(2);
return 1;
}
1
error : Access violation writing location for clone image from std::vector<cv::Mat> and findHomography
can not use std::vector<cv::Mat> imagesF; imagesF.at(0) or imagesF[0] or imagesF[0].clone()
Mat is some kind of smart pointer for the pixels, so Mat a=b will have shared pixels for a and b. similar situation for push_back()
if you need a 'deep copy', use Mat::clone(): imagesF.push_back(imageMat.clone()); https://stackoverflow.com/a/19524261/3533188
When you are using vector to store image from OpenCV Mat you need to use deep copy because cv::Mat is like smart pointer.
std::vector<cv::Mat> imagesVector;
imagesVector.push_back(imageMat.clone());
cv::Mat im_in = imagesVector[0]
#OpenCV #C++ #tiziran
Download first draft for OpenCV 5 book : https://docs.google.com/document/d/1v3qRJE8d0rYXrfDf_BjJHXANTKsPu2lw6In32gD88wY/edit?usp=sharing