OpenCV C++ Error with sinusoidal pattern generation - structured_light library - c++

I am trying to use the sinusoidal pattern tool in C++ with Visual Studio. I have placed the code that I am testing this with below. In visual studio everything looks fine bar the red squiggle under params in the following line:
Ptr<structured_light::SinusoidalPattern> sinus = structured_light::SinusoidalPattern::create(params);
When I try to build I get the following error message:
Severity Code Description Project File Line Suppression State Error (active)
no suitable user-defined conversion from
"cv::structured_light::SinusoidalPattern::Params" to
"cv::Ptr<cv::structured_light::SinusoidalPattern::Params>" exists Structured_Light_Test
c:\Users\ianco\Desktop\CPlusPlus_Programming\Structured_Light_Test\Structured_Light_Test\Main.cpp 70
I would be very grateful if anyone could offer some advice on how I could get round this issue or suggest another method.
CODE:
#include <opencv2/highgui.hpp>
#include <vector>
#include <iostream>
#include <fstream>
#include <opencv2/core.hpp>
#include <opencv2/core/utility.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/structured_light.hpp>
#include <opencv2/phase_unwrapping.hpp>
using namespace cv;
using namespace std;
int main(int argc, char **argv)
{
structured_light::SinusoidalPattern::Params params;
params.width = 1080;
params.height = 700;
params.nbrOfPeriods = 5;
params.setMarkers = true;
params.horizontal = false;
params.methodId = 2;
params.shiftValue = static_cast<float>(2 * CV_PI / 3);
params.nbrOfPixelsBetweenMarkers = 70;
String outputPatternPath = "C:/Users/ianco/Desktop/CPlusPlus_Programming";
String outputWrappedPhasePath = "C:/Users/ianco/Desktop/CPlusPlus_Programming";
String outputUnwrappedPhasePath = "C:/Users/ianco/Desktop/CPlusPlus_Programming";
Ptr<structured_light::SinusoidalPattern> sinus = structured_light::SinusoidalPattern::create(params);
// Storage for patterns
vector<Mat> patterns;
//Generate sinusoidal patterns
sinus->generate(patterns);
cv::Mat blue, green, red;
std::vector<cv::Mat> images(3);
// OpenCV works natively with BGR ordering
images.at(0) = patterns[0];
images.at(1) = patterns[1];
images.at(2) = patterns[2];
cv::Mat color;
cv::merge(images, color);
namedWindow("pattern", WINDOW_NORMAL);
setWindowProperty("pattern", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
imshow("pattern", color);
waitKey(3000);
}

The documentation tells you that params should also be a Ptr but you passed the object...
try using makePtr
Change this line:
structured_light::SinusoidalPattern::Params params;
with this:
Ptr<cv::structured_light::SinusoidalPattern::Params> params = makePtr< SinusoidalPattern::Params >();
you will have to change . to -> for each use of params like params.width = 1080; would be params->width = 1080;, since it will be a pointer now.
The rest of the code should be ok.

Related

Can't load image using openImageIO

I was trying to load image using opeimageio which I installed using vcpkg. But I get an error saying F:\vcpkg\installed\x64-windows\include\OpenImageIO\fmt\format-inl.h(1371,8): error C2061: syntax error: identifier 'HANDLE'. My code is this
#include <OpenImageIO/imageio.h>
#include <string_view>
#include <tuple>
#include <vector>
std::tuple<int, int, int> loadImageFromFile(std::string_view filePath,
std::vector<unsigned char> &data) { auto input = OIIO::ImageInput::open(filePath.data());
auto &specs = input->spec();
int width = specs.width;
int height = specs.height;
int channels = specs.nchannels;
data = std::vector<unsigned char>(width * height * channels);
input->read_image(OIIO::TypeDesc::UINT8, &data[0]);
input->close();
return {width, height, channels};
}
Thanks!

ANN OPENCV error assertion failed

I'm trying to make a simple ANN network with opencv in QT and develop it more later ,
I tried with simple data and i get an error says : OpenCV Error : asserion failed ((unsigned)(i1 *datatype<_tp>::channels)) < unsigned(size.p[1]* channels())) in cv::mat::at
here's the code I wrote
#include <iostream>
#include <opencv2/ml.hpp>
#include <opencv/cv.h>
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "nnet.h"
using namespace std;
using namespace cv;
int main()
{
string filename="data.csv";
Ptr<cv::ml::TrainData> tdata = cv::ml::TrainData::loadFromCSV(filename,0,-1,-1);
Mat trainData = tdata->getTrainSamples();
Mat trainLabels = tdata->getTrainResponses();
int numClasses = 3;
Mat hot(trainLabels.rows, numClasses, CV_32F, 0.0f);
for (int i=0; i<trainLabels.rows; i++) {
int id = (int)trainLabels.at<float>(i);
hot.at<float>(i, id) = 1.0f;
}
int input_neurons = 5;
int hidden_neurons = 5;
int output_neurons = 3;
Mat layerSizes = Mat(3, 1, CV_32SC1);
layerSizes.row(0) = Scalar(input_neurons);
layerSizes.row(1) = Scalar(hidden_neurons);
layerSizes.row(2) = Scalar(output_neurons);
Ptr<cv::ml::ANN_MLP> myNetwork = cv::ml::ANN_MLP::create();
myNetwork->setLayerSizes(layerSizes);
myNetwork->setTrainMethod(ml::ANN_MLP::SIGMOID_SYM);
myNetwork->setTermCriteria(TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 1000, 0.00001f));
myNetwork->setTrainMethod(ml::ANN_MLP::BACKPROP,0.1f,0.1f);
myNetwork->setActivationFunction(ml::ANN_MLP::SIGMOID_SYM, 1, 1);
myNetwork->train(trainData, 0, hot);
string testfilename="test-data.csv";
Ptr<cv::ml::TrainData> testdata = cv::ml::TrainData::loadFromCSV(testfilename, 0,0,-1);
Mat testData = testdata->getTrainSamples();
Mat testLabels = testdata->getTrainResponses();
Mat testResults;
myNetwork->predict(testData, testResults);
float accuracy = float(countNonZero(testResults == testLabels)) / testLabels.rows;
printf("%f",accuracy);
return 0;
}
and for the data set i have
data.csv contains
1,2,3,7,2
7,1,7,7,5
9,7,5,3,2
12,21,32,71,8
and data-test.csv contains :
1,2,1,1,2,
9,1,2,12,5,
11,28,14,50,8,
3,1,2,12,5,
11,28,24,20,8,
thank you in advance for your help.
i found the solution to my problem , in the csv file i've i have 3 classes and the response values should be between [0..2] and i gave random numbers 5 and 8 so changing them solved this problem

Trying to make a live data grapher with CImg library (C++)

I'm new to CImg. Not sure if there's already a live data plotter in the library but I thought I'd go ahead and make one myself. If what I'm looking for already exists in the library please point me to the function. otherwise, here is my super inefficient code that I'm hoping you can help me with~
#include <iostream>
#include "CImg.h"
#include <ctime>
#include <cmath>
using namespace cimg_library;
int main()
{
CImg<unsigned char> plot(400, 320, 1, 3, 0);
CImgDisplay graph(plot, "f(x)");
clock();
const unsigned char red[] = {255, 0, 0};
float* G = new float[plot.width()]; //define an array holding the values that are to be displayed on the graph
while (1){
G[0] = ((plot.height()/4) * sin(clock() / 1000.0)) + plot.height()/2; // new f(t) value
for (int i = 1; i <= plot.width() - 1; i++){
G[plot.width() - i] = G[plot.width() - i - 1]; //basically shift all the array values to current address+1
plot.draw_point(plot.width() - 3*i, G[i-1], red, 1).display(graph);
}
plot.fill(0);
}
return 0;
}
problems
the grapher traverses right to left soo slowly.. and I'm not sure how to make a smooth curve hence I went with points.. how do you make a smooth curve?
There is already something for you in the library, method CImg<T>::draw_graph(), as (brielfy) explained here :
http://cimg.eu/reference/structcimg__library_1_1CImg.html#a2e629aadedc4518001f00333f25bfec8
There are few examples provided with the library that use this method, see files examples/tutorial.cpp and examples/plotter1d.cpp.

BitmapSource copyPixels correct arguments

Used stride by me generates exception. I don't know what stride is correct. The input image is 32 bit JPG. Please tell me what values(I tried many things but they where generating exceptions or corrupted JPG) i should put into:
array<System::Byte>^ pixels = gcnew array<System::Byte>(WHAT VALUE);
bitmapSource->CopyPixels(pixels, WHAT VALUE, 0);
// Jpg.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#using <mscorlib.dll> //requires CLI
using namespace System;
using namespace System::IO;
using namespace System::Windows::Media::Imaging;
using namespace System::Windows::Media;
using namespace System::Windows::Controls;
using namespace std;
[System::STAThread]
int _tmain(int argc, _TCHAR* argv[])
{
// Open a Stream and decode a JPEG image
Stream^ imageStreamSource = gcnew FileStream("C:/heart2.jpg",
FileMode::Open, FileAccess::Read, FileShare::Read);
JpegBitmapDecoder^ decoder = gcnew JpegBitmapDecoder(
imageStreamSource, BitmapCreateOptions::PreservePixelFormat,
BitmapCacheOption::Default);
BitmapSource^ bitmapSource = decoder->Frames[0];//< --mamy bitmape
// Draw the Image
Image^ myImage = gcnew Image();
myImage->Source = bitmapSource;
myImage->Stretch = Stretch::None;
myImage->Margin = System::Windows::Thickness(20);
int width = bitmapSource->PixelWidth;
int height = bitmapSource->PixelHeight;
int stride = (width * bitmapSource->Format.BitsPerPixel + 31) / 32;
array<System::Byte>^ pixels
= gcnew array<System::Byte>(height * width * stride);
bitmapSource->CopyPixels(pixels, stride, 0);
int x;
cin >> x;
return 0;
}
Google
http://msdn.microsoft.com/en-us/library/system.drawing.imaging.bitmapdata.stride.aspx
The stride is the width of a single row of pixels (a scan line), rounded up to a four-byte boundary.
So the correct value depends on how many bits per pixel you have in your image.

Invalid operation while gcnew Image CLI/C++

I get weird information about invalidOperationException in PresentationCore.dll while constructing an image by gcnew Image().
I attach project and the JPG file (which can be put in C:\) It actually cannot be checked other way because configuration of project (references) took a long time, and just copied code will not work.
http://www.speedyshare.com/Vrr84/Jpg.zip
How can I solve that problem?
// Jpg.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#using <mscorlib.dll> //requires CLI
using namespace System;
using namespace System::IO;
using namespace System::Windows::Media::Imaging;
using namespace System::Windows::Media;
using namespace System::Windows::Controls;
int _tmain(int argc, _TCHAR* argv[])
{
// Open a Stream and decode a JPEG image
Stream^ imageStreamSource = gcnew FileStream("C:/heart.jpg", FileMode::Open, FileAccess::Read, FileShare::Read);
JpegBitmapDecoder^ decoder = gcnew JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions::PreservePixelFormat, BitmapCacheOption::Default);
BitmapSource^ bitmapSource = decoder->Frames[0];//< --mamy bitmape
// Draw the Image
Image^ myImage = gcnew Image();//<----------- ERROR
myImage->Source = bitmapSource;
myImage->Stretch = Stretch::None;
myImage->Margin = System::Windows::Thickness(20);
//
int width = 128;
int height = width;
int stride = width / 8;
array<System::Byte>^ pixels = gcnew array<System::Byte>(height * stride);
// Define the image paletteo
BitmapPalette^ myPalette = BitmapPalettes::Halftone256;
// Creates a new empty image with the pre-defined palette.
BitmapSource^ image = BitmapSource::Create(
width, height,
96, 96,
PixelFormats::Indexed1,
myPalette,
pixels,
stride);
System::IO::FileStream^ stream = gcnew System::IO::FileStream("new.jpg", FileMode::Create);
JpegBitmapEncoder^ encoder = gcnew JpegBitmapEncoder();
TextBlock^ myTextBlock = gcnew System::Windows::Controls::TextBlock();
myTextBlock->Text = "Codec Author is: " + encoder->CodecInfo->Author->ToString();
encoder->FlipHorizontal = true;
encoder->FlipVertical = false;
encoder->QualityLevel = 30;
encoder->Rotation = Rotation::Rotate90;
encoder->Frames->Add(BitmapFrame::Create(image));
encoder->Save(stream);
return 0;
}
The core issue is there:
The calling thread must be STA [...]
Your main thread must be marked as a single-threaded apartment (STA for short) for WPF to function correctly. The fix? Add [System::STAThread] to your _tmain, thus informing the runtime that the main thead has to be STA.
[System::STAThread]
int _tmain(int argc, _TCHAR* argv[])
{
// the rest of your code doesn't change
}