Mat::ones not working in OpenCV - c++

int main () {
Mat A = Mat::ones(100, 100, CV_8U)*3;
cout << A.at<int>(0,0) << endl;
return 0;
}
The output is a a very large number :: 50529027
Can anyone help me out?? C++ code

you're casting to the wrong type in A.at<int>() // should be uchar instead of int
so, A.at<int>(0,0) sees 0x03030303, which is, in fact 50529027.
Mat A = Mat::ones(100, 100, CV_8U)*3;
cout << int(A.at<uchar>(0,0)) << endl;
(the cast around A.at() is just to show a number with cout instead of a char )

Related

Segmentation Fault in creating a cv::Mat from unsigned char array

I cannot understand why the following minimal code outputs segmentation fault and cv::Mat values are not printed correctly:
#include <opencv2/opencv.hpp>
int main()
{
unsigned char out[1280*720*3/2] = {100};
cv::Mat dummy_query = cv::Mat(1, 1280*720*3/2*sizeof(unsigned char), CV_8UC1, (void *)out);
cv::Size s = dummy_query.size();
std::cout << s << "\r\n";
for(int i = 0; i < 1280*720*3/2; i++)
{
std::cout << i << "ss" << int(out[i]) << ":";
std::cout << dummy_query.at<int>(0,i) << " ";
}
}
You have defined uchar datatype in cv::Mat but accessing at this line
as int std::cout << dummy_query.at<int>(0,i) << " ";
so your program will likely get crash at end of the loop
e.g.
// create a 100x100 8-bit matrix
Mat M(100,100,CV_8U);
// this will be compiled fine. no any data conversion will be done.
Mat_<float>& M1 = (Mat_<float>&)M;
// the program is likely to crash at the statement below
M1(99,99) = 1.f;
check this open cv reference

How to use MPIR Prime testers mpz_likely_prime_p and mpz_probable_prime_p?

I'm trying to use MPIR's prime tester(s) for rapid non-sequential testing; however, I'm new to MPIR and am confused about their usage - specifically the "gmp_randstate_t" parameter used by the function. Here's what I've got so far:
#include<iostream> // used for cout
#include<mpir.h>
int main() {
mpz_t PrimeCanidate;
mpz_init(PrimeCanidate);
mpz_set_ui(PrimeCanidate, 3); // sets PrimeCanidate to unsigned int "3"
if (mpz_likely_prime_p(PrimeCanidate) == 1) {
std::cout << "Number is prime: " << std::endl;
}
}
As I'm only using one parameter inside mpz_likely_prime_p, it doesn't work - I just don't know what it's looking for with the other parameters (state, div) as shown in the documentation (http://www.mpir.org/mpir-3.0.0.pdf pg. 42):
Would anybody by chance have a simple code that uses the prime-testing functions in MPIR? Thanks a ton.
After a bunch of tinkering, I figured out how to properly initialize the "state" and div" parameters for mpz_likely_prime_p. Here's an example calculating and printing primes between 1 and 100:
#include<iostream> // used for cout
#include<mpir.h>
int main() {
mpz_t PrimeCanidate;
mpz_init(PrimeCanidate);
mpz_set_ui(PrimeCanidate, 2);
mpz_t additor;
mpz_init(additor);
mpz_set_ui(additor, 1);
gmp_randstate_t state;
gmp_randinit_default(state);
mpir_ui div = 0;
int maxbase = 100;
for (int base = 2; base < maxbase; base++) {
mpz_add(PrimeCanidate, PrimeCanidate, additor); // repeatedly adds one to PrimeCanidate
std::cout << "Tested Number: " << PrimeCanidate << std::endl;
if (mpz_likely_prime_p(PrimeCanidate, state, div) == 1) {
std::cout << PrimeCanidate << " is prime." << std::endl;
}
}
}
This is probably not optimal, but it works and might be a good place to start.

C++ Opencv: Mat.zeros get wrong shape

I defined and initialized a Mat variable using the Mat::zeros, when I print its shape, i.e. rows, cols, channels, it seems I get wrong values.
My code is shown as follows:
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char const *argv[])
{
int n_Channel = 3;
int mySizes[3] = {100, 200, n_Channel};
Mat M = Mat::zeros(n_Channel, mySizes, CV_64F);
cout << M.rows << "," << M.cols << "," << M.channels() << endl;
return 0;
}
The printed message is :
-1,-1,1
What's wrong with this?
I also find that if I declare a Mat using the following code:
int n_Channel = 3;
Mat M(Size(100, 200), CV_32FC(n_Channel));
cout << M.rows << "," << M.cols << "," << M.channels() << endl;
the outcome is correct:
200,100,3
I'm confused about this. Thank you all for helping me!
You want to use a very special overloaded version of the cv::Mat::zeros method.
Let's have a look at the following code:
// Number of channels.
const int n_Channel = 3;
// Number of dimensions; must be 1 or 2?
const int n_Dimensions = 2;
// Create empty Mat using zeros, and output dimensions.
int mySizes[n_Dimensions] = { 200, 100 };
cv::Mat M1 = cv::Mat::zeros(n_Dimensions, mySizes, CV_64FC(n_Channel));
std::cout << "M1: " << M1.rows << "," << M1.cols << "," << M1.channels() << std::endl;
// Create empty Mat using constructor, and output dimensions.
cv::Mat M2 = cv::Mat(cv::Size(100, 200), CV_64FC(n_Channel), cv::Scalar(0, 0, 0));
std::cout << "M2: " << M2.rows << "," << M2.cols << "," << M2.channels() << std::endl;
which gives the following output:
M1: 200,100,3
M2: 200,100,3
So, basically you have to move the "channel number info" from mySizes to the cv::Mat::zeros method. Also, you have to pay attention to the order of the image dimensions provided in mySizes, since it seem to differ from the constructor using cv::Size. I guess the latter one is width x height, whereas the first one is number of rows x number of cols.
How to init CV mat :
cv::Mat test = cv::Mat::zeros(cv::Size(100, 200), CV_64F);
As you can see, the first parameter is the Size cf :
https://docs.opencv.org/3.1.0/d3/d63/classcv_1_1Mat.html

Magick++ Issue when converting to Mat Opencv

Good day everyone,
I have this problem which I need to convert the Magick++ Image to OpenCV Mat. Though I successfully converted it however the problem occurs which the color of the Mat is not correct (Please see attached Image). In my case, I have a PDF file which I converted it to Magick++ Image page by page and to use my Image Processing methods, I need to convert it to OpenCV Mat. When I use other PDF file, the colors are correct. I really appreciate any help in this issue, Thanks.
My working code is displayed below, thanks.
Note: I use ImageMagick-7.0.6-Q16 and OpenCV 2.4.11
try {
string fName = "";
vector<Magick::Image> imageList;
cout << "Please Input the File name of the PDF." << endl;
cin >> fName;
cout << "Please wait while converting the PDF to Images...." << endl;
readImages(&imageList, fName);
bool isDecoded = false;
for (int i = 0; i < imageList.size(); i++){
if (!isDecoded){
int w = imageList[i].columns();
int h = imageList[i].rows();
Mat opencvImage(h,w,CV_8UC4);
imageList[i].write(0, 0, w, h, "RGBA" , Magick::CharPixel, opencvImage.data);
string decoded = QRScanner(opencvImage);
imshow("opencvImage", opencvImage);
if (decoded != ""){
cout << "Result: " << decoded << endl;
isDecoded = true;
}
waitKey();
}
}
}
catch (Magick::Exception &error_)
{
cout << "Caught exception: " << error_.what() << endl;
}
cout << "Convert Complete!" << endl;
system("pause");
Sample Code
Image Problem
I think the majority of the problem has been addressed in the comments above, but I believe this can be quickly fixed by adjusting the channel map to what OpenCV is expecting.
imageList[i].write(0, 0, w, h, "BGRA" , Magick::CharPixel, opencvImage.data);
^^^^
No need to worry about cvtColor or negation as you already can control how the data stream is exported.

Error when attempting to use max_element to figure out the highest number in an array

int a = max_element(highesthuman[0], highesthuman[2]);
if( win > loss)
{
cout << "You won " << (win-loss) << " games more than the computer did! You used " << a << " the most.";
}
}
The above array is given by
int humanrock = 0;
int humanpaper = 0;
int humanscissors = 0;
int highesthuman [3] = {humanrock, humanpaper, humanscissors};
When running my whole program I get an error saying "invalid type argument of unary". I looked this up but was not able to understand "pointers" or what people were referring too.
std::max_element() accepts two iterators as parameters, and returns an iterator. In your case iterators are pointers. So you should change
int a = max_element(highesthuman[0], highesthuman[2]);
to
int a = *max_element(highesthuman, highesthuman + 3);