OpenCV equivalent for Matlab's rdivide? - matlab

For example we have expression using rdivide in Matlab:
B = bsxfun(#rdivide, A, A(4,:));
How can we write equavalent expression for opencv?
Opencv has divide function, but seems it can't be used for matrix with different dimensions:
Mat t1= Mat::ones(2,3,CV_64FC1);
Mat t2= Mat::ones(1,3,CV_64FC1);
Mat dst;
divide(t1,t2,dst);
this don't work, so we need to replicate one row to matrix to match dimensions of t1 or use divide with 1 row in cycle.
My solution for opencv(A modified inplace):
for(int i=0;i<A.rows;++i)
{
divide(A.row(i),A.row(3),A.row(i));
}
Is there any simpler way?

You can use the repeat function of OpenCV to replicate a matrix.
The equivalent OpenCV code for the above mentioned MATLAB command is following:
cv::Mat B = A/cv::repeat(A.row(3),4,1);

In addition to #sgarizvi solution, you may find this wrapper to Matlab rdivide helpful:
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat rdivide(const Mat& A, const Mat& B)
{
int nx = A.cols / B.cols;
int ny = A.rows / B.rows;
return A / repeat(B, ny, nx);
}
Mat rdivide(const Mat& A, double d)
{
return A / d;
}
int main()
{
Mat1f A = (Mat1f(3, 5) << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
Mat B = rdivide(A, A.row(2)); // Divide by matrix, works also for cols: e.g. A.col(2)
Mat C = rdivide(A, 2); // Divide by scalar
cout << "A: " << endl << A << endl << endl;
cout << "B: " << endl << B << endl << endl;
cout << "C: " << endl << C << endl << endl;
return 0;
}

Related

My vscode is part English part Chinese, how to change it to complete English?

As mentioned in the title, I have part of my vscode Chinese, which is troublesome since looking up error codes in English will be easier. How can I turn it into complete English? I've tried How to set Visual Studio Code Terminal output to English and it didn't work for me.
Since someone asked for the code to be post in text, this is the code (I'm using a tutorial code for camera calibration from opencv, so the error code appearing also confused me):
#include <iostream>
#include <opencv2/calib3d.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
int main(int argc, char **argv) {
(void)argc;
(void)argv;
std::vector<cv::String> fileNames;
cv::glob("../calibration/Image*.png", fileNames, false);
cv::Size patternSize(25 - 1, 18 - 1);
std::vector<std::vector<cv::Point2f>> q(fileNames.size());
std::vector<std::vector<cv::Point3f>> Q;
// 1. Generate checkerboard (world) coordinates Q. The board has 25 x 18
// fields with a size of 15x15mm
int checkerBoard[2] = {25,18};
// Defining the world coordinates for 3D points
std::vector<cv::Point3f> objp;
for(int i = 1; i<checkerBoard[1]; i++){
for(int j = 1; j<checkerBoard[0]; j++){
objp.push_back(cv::Point3f(j,i,0));
}
}
std::vector<cv::Point2f> imgPoint;
// Detect feature points
std::size_t i = 0;
for (auto const &f : fileNames) {
std::cout << std::string(f) << std::endl;
// 2. Read in the image an call cv::findChessboardCorners()
cv::Mat img = cv::imread(fileNames[i]);
cv::Mat gray;
cv::cvtColor(img, gray, cv::COLOR_RGB2GRAY);
bool patternFound = cv::findChessboardCorners(gray, patternSize, q[i], cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE + cv::CALIB_CB_FAST_CHECK);
// 2. Use cv::cornerSubPix() to refine the found corner detections
if(patternFound){
cv::cornerSubPix(gray, q[i],cv::Size(11,11), cv::Size(-1,-1), cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.1));
Q.push_back(objp);
}
// Display
cv::drawChessboardCorners(img, patternSize, q[i], patternFound);
cv::imshow("chessboard detection", img);
cv::waitKey(0);
i++;
}
cv::Matx33f K(cv::Matx33f::eye()); // intrinsic camera matrix
cv::Vec<float, 5> k(0, 0, 0, 0, 0); // distortion coefficients
std::vector<cv::Mat> rvecs, tvecs;
std::vector<double> stdIntrinsics, stdExtrinsics, perViewErrors;
int flags = cv::CALIB_FIX_ASPECT_RATIO + cv::CALIB_FIX_K3 +
cv::CALIB_ZERO_TANGENT_DIST + cv::CALIB_FIX_PRINCIPAL_POINT;
cv::Size frameSize(1440, 1080);
std::cout << "Calibrating..." << std::endl;
// 4. Call "float error = cv::calibrateCamera()" with the input coordinates
// and output parameters as declared above...
float error = cv::calibrateCamera(Q, q, frameSize, K, k, rvecs, tvecs, flags);
std::cout << "Reprojection error = " << error << "\nK =\n"
<< K << "\nk=\n"
<< k << std::endl;
// Precompute lens correction interpolation
cv::Mat mapX, mapY;
cv::initUndistortRectifyMap(K, k, cv::Matx33f::eye(), K, frameSize, CV_32FC1,
mapX, mapY);
// Show lens corrected images
for (auto const &f : fileNames) {
std::cout << std::string(f) << std::endl;
cv::Mat img = cv::imread(f, cv::IMREAD_COLOR);
cv::Mat imgUndistorted;
// 5. Remap the image using the precomputed interpolation maps.
cv::remap(img, imgUndistorted, mapX, mapY, cv::INTER_LINEAR);
// Display
cv::imshow("undistorted image", imgUndistorted);
cv::waitKey(0);
}
return 0;
}

Is there a space efficient way to compute the gcd of high exponents?

Basically, I am writing a program that works with large integer values that overflow the cpp integer. I am trying to compute something like: gdc(pow(a, b), c) where a ^ b is the value overflowing the integer limit. Is there a way to do this where I don't have to rely on big integer libraries? If not, are there any recommended big integer libraries?
We can use a property of greatest common divisor that gcd(a, b) = gcd(a % b, b). Hence gcd(pow(a, b), c) = gcd(pow(a, b) % c, c) = gcd(powmod(a, b, c), c), where powmod() is modular exponentiation.
In my C++ code below PowMod() is implemented using exponentiation by squaring approach.
Try it online!
#include <cstdint>
#include <iostream>
using Word = uint32_t;
using DWord = uint64_t;
Word GCD(Word a, Word b) {
Word t = 0;
while (b != 0) {
t = b;
b = a % b;
a = t;
}
return a;
}
Word PowMod(Word a, Word b, Word c) {
Word r = 1;
while (b != 0) {
if (b & 1)
r = (DWord(r) * a) % c;
a = (DWord(a) * a) % c;
b >>= 1;
}
return r;
}
int main() {
Word const
a = 2645680092U, b = 3562429202U, c = 3045001828U,
powmod = PowMod(a, b, c), gcd = GCD(powmod, c);
std::cout << "a = " << a << ", b = " << b
<< ", c = " << c << std::endl;
std::cout << "PowMod(a, b, c) = "
<< powmod << std::endl; // 592284924
std::cout << "GCD(PowMod(a, b, c), c) = "
<< gcd << std::endl; // 1892
}
Output:
a = 2645680092, b = 3562429202, c = 3045001828
PowMod(a, b, c) = 592284924
GCD(PowMod(a, b, c), c) = 1892
which gives correct results, that can be verified through following simple Python program giving same result:
Try it online!
import random, math
random.seed(0)
bits = 32
while True:
c = random.randrange(1 << (bits - 1), 1 << bits)
a = random.randrange(1 << (bits - 1), 1 << bits) % c
b = random.randrange(1 << (bits - 1), 1 << bits)
pm = pow(a, b, c)
gcd = math.gcd(pm, c)
if gcd >= 1000:
print('a =', a, ', b =', b, ', c =', c,
', powmod =', pm, ', gcd =', gcd)
break
Output:
a = 2645680092 , b = 3562429202 , c = 3045001828 ,
powmod = 592284924 , gcd = 1892
If you have GCC/CLang compiler, you can make Word to be 64-bit and DWord to be 128-bit, by changing following lines of code:
using Word = uint64_t;
using DWord = unsigned __int128;
my code supports 32-bit inputs, but after this change you can have 64-bit inputs.
Part 2. Using large integer arithmetics library GMP.
If for some reason you have large input integers then you can use great library GMP for large arithmetics (it supports integer, rational, floating point numbers).
This library has all mathematical operations, including modular exponentiation (PowMod) and some number theoretical functions (including GCD). Also this library is very popular and highly optimized.
In following code I do same things like in me code above, but using only GMP's functions. As an example I use 512-bit integers to show that it can accept large inputs (it can accept even millions of digits):
Try it online!
#include <iostream>
#include <cstdlib>
#include <gmpxx.h>
int main() {
mpz_class const
a("1953143455988359840868749111326065201169739169335107410565117106311318704164104986194255770982854472823807334163384557922525376038346976291413843761504166", 10),
b("5126002245539530470958611905297854592859344951467500786493685495603638740444446597426402800257519403404965463713689509774040138494219032682986554069941558", 10),
c("4396071968291195248321035664209400217968667450140674696924686844534284953565382985421958604880273584922294910355449271193696338132720472184903935323837626", 10);
mpz_class powmod, gcd;
// PowMod
mpz_powm(powmod.get_mpz_t(), a.get_mpz_t(), b.get_mpz_t(), c.get_mpz_t()); // 1632164707041502536171492944083090257113212090861915134477312917063125646194834706890409016008321666479437224930114914370387958138698748075752168351835856
// GCD
mpz_gcd(gcd.get_mpz_t(), powmod.get_mpz_t(), c.get_mpz_t()); // 51842
// Output
std::cout << "PowMod = " << powmod.get_str() << std::endl
<< "GCD = " << gcd.get_str() << std::endl;
}
Output:
PowMod = 1632164707041502536171492944083090257113212090861915134477312917063125646194834706890409016008321666479437224930114914370387958138698748075752168351835856
GCD = 51842
To use GMP library under Linux just install sudo apt install libgmp-dev and compile clang++ -std=c++11 -O2 -lgmp -o main main.cpp.
Using GMP under Windows is a bit more tricky. One way is to build yourself MPIR library which is a Windows friendly clone of GMP. Another way is to install MSYS and use prebuilt GMP from there following these instructions that I wrote in my other answer.

Eigen: how can I substitute matrix positive values with 1 and 0 otherwise?

I want to write the following matlab code in Eigen (where K is pxp and W is pxb):
H = (K*W)>0;
However the only thing that I came up so far is:
H = ((K*W.array() > 0).select(1,0));
This code doesn't work as explained here, but replacing 0 with VectorXd::Constant(p,0) (as suggested in the link question) generates a runtime error:
Eigen::internal::variable_if_dynamic<T, Value>::variable_if_dynamic(T) [with T = long int; int Value = 1]: Assertion `v == T(Value)' failed.
How can I solve this?
You don't need .select(). You just need to cast an array of bool to an array of H's component type.
H = ((K * W).array() > 0.0).cast<double>();
Your original attempt failed because the size of your constant 1/0 array is not match with the size of H. Using VectorXd::Constant is not a good choice when H is MatrixXd. You also have a problem with parentheses. I think you want * rather than .* in matlab notation.
#include <iostream>
#include <Eigen/Eigen>
using namespace Eigen;
int main() {
const int p = 5;
const int b = 10;
MatrixXd H(p, b), K(p, p), W(p, b);
K.setRandom();
W.setRandom();
H = ((K * W).array() > 0.0).cast<double>();
std::cout << H << std::endl << std::endl;
H = ((K * W).array() > 0).select(MatrixXd::Constant(p, b, 1),
MatrixXd::Constant(p, b, 0));
std::cout << H << std::endl;
return 0;
}
When calling a template member function in a template, you need to use the template keyword.
#include <iostream>
#include <Eigen/Eigen>
using namespace Eigen;
template<typename Mat, typename Vec>
void createHashTable(const Mat &K, Eigen::MatrixXi &H, Mat &W, int b) {
Mat CK = K;
H = ((CK * W).array() > 0.0).template cast<int>();
}
int main() {
const int p = 5;
const int b = 10;
Eigen::MatrixXi H(p, b);
Eigen::MatrixXf W(p, b), K(p, p);
K.setRandom();
W.setRandom();
createHashTable<Eigen::MatrixXf, Eigen::VectorXf>(K, H, W, b);
std::cout << H << std::endl;
return 0;
}
See this for some explanation.
Issue casting C++ Eigen::Matrix types via templates

How to use a struct passed by value in Red/System from a DLL

I have some c code that looks like this:
extern "C" __declspec(dllexport) inline sfVector2f __cdecl sf_vector_create(
float x, float y
) {
std::cout << "x: " << x << " y: " << y << std::endl;
sfVector2f vec = {x,y}; // just a struct of two floats
return vec;
}
extern "C" __declspec(dllexport) inline void __cdecl test(
sfSprite* sprite, sfVector2f wtf
) {
std::cout << wtf.x << " " << wtf.y << std::endl;
sfSprite_setPosition(sprite, wtf);
}
I invoke it from reds like this:
vec: sf-vector-create as float32! 100.0 as float32! 100.0
test mario-sprite vec
When I invoke this in reds, I get garbled results... why?
The C code is returning the vec struct on stack instead of returning a struct pointer. So in R/S, I guess you get back only the first entry of the struct. R/S does not yet support passing structs by value. But you can retrieve the rest of the values by some clever use of system/stack/* accessors to get a pointer on the beginning of the struct.
Something like this should work:
sf-vector-create as float32! 100.0 as float32! 100.0
p: as byte-ptr! system/stack/top
vec: as vector! p - size? vector!
(Answer from #DocKimbel)

how to convert variable type integer to double

I want to convert integers to double in the following piece of code:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a , b;
double c;
cout<<"Enter two integers: ";
cin>>a>>b;
try
{
if (b == 0)
throw 0;
}
catch (int a)
{
cout<<"You made a division by zero?"<<endl<<a;
}
c = static_cast<double>(a/b);
cout<<"The division is: "<<fixed<<setprecision(2)<<c;
}
How to change the code to output the double value?
As mentioned you should cast not a result of division but variables itself, to get double value. All three options works.
int a, b;
double c;
std::cout << "Enter two integers: ";
std::cin >> a >> b;
try
{
if (b == 0)
throw 0;
}
catch (int a)
{
std::cout << "You made a division by zero?" << std::endl << a;
}
c = static_cast<double>(a) / b;
c = a / static_cast<double>(b);
c = static_cast<double>(a) / static_cast<double>(b);
std::cout << "The division is: " << std::fixed << std::setprecision(2) << c;
std::cin >> a >> b;
You are casting the result of the division, you should cast the operands instead.
Don't use an exception to catch a condition that you already catch using a simple if. Just use the if, and use an else to skip the division if the second operand is zero.
int a , b;
double c;
cout<<"Enter two integers: ";
cin>>a>>b;
if (b == 0) {
cout<<"You made a division by zero?"<<endl;
} else {
c = static_cast<double>(a) / static_cast<double>(b);
cout<<"The division is: "<<fixed<<setprecision(2)<<c;
}