How can I convert a CImg image to an itkImage? - c++

I have a CImg image (with double values) with the following form in c++:
CImg<double> image(512,512);
Tcyl.fill(1);
I would like to use ITK functionality to transform this image. So I need to transform this CImg image into itkImage object. How can I convert?

I have never used ITK before, so this was a learning curve. Anyway, I managed to make a radial gradient of floats in CImg and convert that to an ITK image and then write that as a float TIFF.
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
#include "itkImage.h"
#include "itkImportImageFilter.h"
#include "itkImageFileWriter.h"
#include "itkTIFFImageIO.h"
using namespace cimg_library;
using namespace std;
#define W 512
#define H 512
int main() {
// Create and initialise float image with radial gradient
cimg_library::CImg<float> img(W,H);
cimg_forXY(img,x,y) {img(x,y) = hypot((float)(W/2-x),(float)(H/2-y)); }
// Now convert CImg image to ITK image
const unsigned int Dimension = 2;
typedef itk::Image<float,Dimension> InputImageType;
typedef itk::ImportImageFilter<float,Dimension> ImportFilterType;
ImportFilterType::Pointer importFilter = ImportFilterType::New();
InputImageType::SizeType imsize;
imsize[0] = img.width();
imsize[1] = img.height();
ImportFilterType::IndexType start;
start.Fill(0);
ImportFilterType::RegionType region;
region.SetIndex(start);
region.SetSize(imsize);
importFilter->SetRegion(region);
const itk::SpacePrecisionType origin[Dimension] = {0.0,0.0};
importFilter->SetOrigin(origin);
const itk::SpacePrecisionType spacing[Dimension] = {1.0,1.0};
importFilter->SetSpacing(spacing);
// Tell ITK importFilter to take pixels directly from CImg's buffer
importFilter->SetImportPointer(img.data(),imsize[0]*imsize[1],false);
// Write result as a TIFF - so I can check it worked
typedef itk::ImageFileWriter<InputImageType> WriterType;
typedef itk::TIFFImageIO TIFFIOType;
TIFFIOType::Pointer tiffIO = TIFFIOType::New();
tiffIO->SetPixelType(itk::ImageIOBase::SCALAR);
WriterType::Pointer writer = WriterType::New();
writer->SetFileName("result.tif");
writer->SetInput(importFilter->GetOutput());
writer->SetImageIO(tiffIO);
writer->Update();
}
And here's the result (converted to JPEG for SO):
It works just the same if you change float for double except you can't write doubles to a TIFF so the last bit won't work.
I've been messing around some more and managed to load the pixels into a new ITK image ready for further processing, rather than for output:
#include <iostream>
#include <cstdlib>
#define cimg_display 0
#include "CImg.h"
#include "itkImage.h"
#include "itkImageRegionIterator.h"
using namespace cimg_library;
using namespace std;
#define W 5
#define H 3
int main() {
// Create and initialise double image with simple formula
cimg_library::CImg<double> img(W,H);
cimg_forXY(img,x,y) {img(x,y) = (double)x+(10.0*(double)y); }
// Now convert CImg image to ITK image
const unsigned int Dimension = 2;
typedef itk::Image<double,2> ImageType;
ImageType::Pointer image = ImageType::New();
ImageType::SizeType size;
size[0] = img.width();
size[1] = img.height();
ImageType::IndexType start;
start.Fill(0);
ImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);
image->SetRegions(region);
image->Allocate();
double origin[2];
origin[0]=0;
origin[1]=0;
image->SetOrigin(origin);
double spacing[2];
spacing[0]=1;
spacing[1]=1;
image->SetSpacing(spacing);
typedef itk::ImageRegionIterator<ImageType> IteratorType;
IteratorType it(image,region);
it.GoToBegin();
const double* data = img.data();
while(!it.IsAtEnd()){
it.Set(*data);
++it;
++data;
}
// Display pixels for checking purposes
for(unsigned int r = 0; r < H; r++)
{
for(unsigned int c = 0; c < W; c++)
{
ImageType::IndexType pixelIndex;
pixelIndex[0] = c;
pixelIndex[1] = r;
ImageType::PixelType pixelValue = image->GetPixel( pixelIndex );
cout << "Image[" << r << "," << c << "]: " << pixelValue << endl;
}
}
}
Sample Output
Image[0,0]: 0
Image[0,1]: 1
Image[0,2]: 2
Image[0,3]: 3
Image[0,4]: 4
Image[1,0]: 10
Image[1,1]: 11
Image[1,2]: 12
Image[1,3]: 13
Image[1,4]: 14
Image[2,0]: 20
Image[2,1]: 21
Image[2,2]: 22
Image[2,3]: 23
Image[2,4]: 24

Related

Using Tensorflow Lite C, Digit Classifier

Using Tensorflow Lite, on Android,
Image classification was successful.
Example: https://github.com/tensorflow/examples/tree/master/lite/codelabs/digit_classifier
core : https://github.com/tensorflow/examples/blob/master/lite/codelabs/digit_classifier/android/finish/app/src/main/java/org/tensorflow/lite/codelabs/digitclassifier/DigitClassifier.kt
I want to convert this project to C.
The image(.jpg) will be read using opencv.
The model file is (.tflite)
Give me some advice.
This is my program code.
#include <iostream>
#include <iomanip>
#include <fstream>
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tensorflow/lite/optional_debug_tools.h"
#include "opencv2/opencv.hpp"
using namespace std;
typedef cv::Point3_<float> Pixel;
const uint WIDTH = 28;
const uint HEIGHT = 28;
const uint CHANNEL = 3;
const uint OUTDIM = 10;
void normalize(Pixel &pixel){
pixel.x = (pixel.x / 255.0);
pixel.y = (pixel.y / 255.0);
pixel.z = (pixel.z / 255.0);
}
int main(){
std::vector<std::string> labels;
auto file_name="labels.txt";
std::ifstream input( file_name );
for( std::string line; getline( input, line ); )
{
labels.push_back( line);
}
// read image file
cv::Mat img = cv::imread("sample2.jpg");
cv::Mat inputImg;
img.convertTo(inputImg, CV_32FC3);
cv::cvtColor(inputImg, inputImg, cv::COLOR_BGR2RGB);
// normalize to -1 & 1
Pixel* pixel = inputImg.ptr<Pixel>(0,0);
const Pixel* endPixel = pixel + inputImg.cols * inputImg.rows;
for (; pixel != endPixel; pixel++)
normalize(*pixel);
// resize image as model input
cv::resize(inputImg, inputImg, cv::Size(WIDTH, HEIGHT));
// create model
std::unique_ptr<tflite::FlatBufferModel> model =
tflite::FlatBufferModel::BuildFromFile("mnist.tflite");
tflite::ops::builtin::BuiltinOpResolver resolver;
std::unique_ptr<tflite::Interpreter> interpreter;
tflite::InterpreterBuilder(*model.get(), resolver)(&interpreter);
interpreter->AllocateTensors();
float* inputLayer = interpreter->typed_input_tensor<float>(0);
float* inputImg_ptr = inputImg.ptr<float>(0);
memcpy(inputLayer, inputImg.ptr<float>(0),
WIDTH * HEIGHT * CHANNEL * sizeof(float));
interpreter->Invoke();
float* outputLayer = interpreter->typed_output_tensor<float>(0);
// TODO
return 0;
}
Summary of this question : Android -> C Convert
The result I wantPrediction Result : 6Confidence: 0~1
.tflite model file is here

How do I properly use the OpenH264 Usage Code Example for Encoding?

I have an image and want to encode it with OpenH264.
So far this is the code I derived from their wiki:
#include <fstream>
#include <iterator>
#include <iostream>
#include <codec_api.h> //standard api for openh264
//additional libaries used by sample code
#include <codec_app_def.h>
#include <codec_def.h>
#include <codec_ver.h>
#include <assert.h>
#include <vector>
#include <cstring>
int main()
{
//parameter values
int width = 1920;
int height = 1080;
int framerate = 60;
int bitrate = 5000000;
int total_num = 500; //what does this value do?
//end parameter values
//Read in the File from bmp
std::vector<char> buf; //to store the image information
std::basic_ifstream<char> file("/home/megamol/Git/h264_sample/build/test.bmp", std::ios::binary); //opens bitstream to source
buf = std::vector<char>((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>()); // reads in data to the vector
std::cout << "sizeof buf: " << buf.size() << std::endl;
//Step 1: set up Encoder
ISVCEncoder* encoder_; //declaration of encoder pointer
int rv = WelsCreateSVCEncoder (&encoder_);
//Step 2: initialize with basic parameter
SEncParamBase param;
memset(&param, 0, sizeof (SEncParamBase));
param.iUsageType = EUsageType::SCREEN_CONTENT_REAL_TIME;
param.fMaxFrameRate = framerate;
param.iPicWidth = width;
param.iPicHeight = height;
param.iTargetBitrate = bitrate; //default value of example
encoder_->Initialize(&param);
//Step 3: set video format
int videoFormat = videoFormatI420;
encoder_->SetOption (ENCODER_OPTION_DATAFORMAT, &videoFormat);
//Step 4: encocode and store output bitstream
int frameSize = width * height * 3 / 2;
buf.resize(frameSize);
SFrameBSInfo info;
std::vector<char> compressedData;
memset (&info, 0, sizeof (SFrameBSInfo));
SSourcePicture pic;
memset (&pic, 0, sizeof (SSourcePicture));
pic.iPicWidth = width;
pic.iPicHeight = height;
pic.iColorFormat = videoFormatI420;
pic.iStride[0] = pic.iPicWidth;
pic.iStride[1] = pic.iStride[2] = pic.iPicWidth >> 1;
pic.pData[0] = reinterpret_cast<unsigned char*>(&buf[0]);
pic.pData[1] = pic.pData[0] + width * height;
pic.pData[2] = pic.pData[1] + (width * height >> 2);
//encodes the frame
rv = encoder_->EncodeFrame (&pic, &info); // encodes the Frame
//encoding done encoded Frame should be stored in &info
//begin decoding block
ISVCDecoder *pSvcDecoder;
unsigned char *pBuf= &info;
return 0;
}
I'm not entirely sure whether this is the correct usage of OpenH264 but I'm also not sure how to test it properly.
Now the code example is kind of poorly documented.
What is BufferedData buf; for example? I get that that's supposed to be the input but what is that type? Like how do I load my test.bmp as BufferedData? I don't think that I'm doing that correctly yet.
Another thing I'm pretty confused about is how do I access the output after the encoding? In the example it just says //output bitstream and nothing about saving this output anywhere. I thought the output was info like it says in the codec_api.h header file:
/**
* #brief Encode one frame
* #param kpSrcPic the pointer to the source luminance plane
* chrominance data:
* CbData = kpSrc + m_iMaxPicWidth * m_iMaxPicHeight;
* CrData = CbData + (m_iMaxPicWidth * m_iMaxPicHeight)/4;
* the application calling this interface needs to ensure the data validation between the location
* #param pBsInfo output bit stream
* #return 0 - success; otherwise -failed;
*/
virtual int EXTAPI EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSInfo* pBsInfo) = 0;
But apparently it only saves informations about the output. I'm just really confused about all of this.
Based on https://github.com/cisco/openh264/blob/master/codec/console/enc/src/welsenc.cpp
#include <codec_api.h>
#include <cassert>
#include <cstring>
#include <vector>
#include <fstream>
#include <iostream>
//Tested with OpenCV 3.3
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
ISVCEncoder *encoder_ = nullptr;
int rv = WelsCreateSVCEncoder (&encoder_);
assert (0==rv);
assert (encoder_ != nullptr);
int width = 640;
int height = 480;
int total_num = 100;
SEncParamBase param;
memset (&param, 0, sizeof (SEncParamBase));
param.iUsageType = CAMERA_VIDEO_REAL_TIME;
param.fMaxFrameRate = 30;
param.iPicWidth = width;
param.iPicHeight = height;
param.iTargetBitrate = 5000000;
encoder_->Initialize (&param);
Mat image = imread("test.jpg", IMREAD_COLOR );
Mat imageResized, imageYuv, imageYuvMini;
resize(image, imageResized, Size(width, height));
Mat imageYuvCh[3], imageYuvMiniCh[3];
cvtColor(imageResized, imageYuv, cv::COLOR_BGR2YUV);
split(imageYuv, imageYuvCh);
resize(imageYuv, imageYuvMini, Size(width/2, height/2));
split(imageYuvMini, imageYuvMiniCh);
SFrameBSInfo info;
memset (&info, 0, sizeof (SFrameBSInfo));
SSourcePicture pic;
memset (&pic, 0, sizeof (SSourcePicture));
pic.iPicWidth = width;
pic.iPicHeight = height;
pic.iColorFormat = videoFormatI420;
pic.iStride[0] = imageYuvCh[0].step;
pic.iStride[1] = imageYuvMiniCh[1].step;
pic.iStride[2] = imageYuvMiniCh[2].step;
pic.pData[0] = imageYuvCh[0].data;
pic.pData[1] = imageYuvMiniCh[1].data;
pic.pData[2] = imageYuvMiniCh[2].data;
ofstream outFi;
outFi.open ("test.264", ios::out | ios::binary);
for(int num = 0; num<total_num; num++)
{
//prepare input data
rv = encoder_->EncodeFrame (&pic, &info);
assert (rv == cmResultSuccess);
if (info.eFrameType != videoFrameTypeSkip /*&& cbk != nullptr*/)
{
//output bitstream
for (int iLayer=0; iLayer < info.iLayerNum; iLayer++)
{
SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayer];
int iLayerSize = 0;
int iNalIdx = pLayerBsInfo->iNalCount - 1;
do {
iLayerSize += pLayerBsInfo->pNalLengthInByte[iNalIdx];
--iNalIdx;
} while (iNalIdx >= 0);
unsigned char *outBuf = pLayerBsInfo->pBsBuf;
outFi.write((char *)outBuf, iLayerSize);
}
}
}
if (encoder_) {
encoder_->Uninitialize();
WelsDestroySVCEncoder (encoder_);
}
outFi.close();
}

C++/OpenCV Bicubic resize of an RGB image

I want to resize an RGB image with the Bicubic interpolation. I used the following code :
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <ctime>
#include <iostream>
using namespace std;
//#include <opencv.hpp>
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv/highgui.h>
using namespace cv;
int main()
{
string fileName = "myImage.jpg";
Mat imageSrc = cv::imread(fileName, CV_LOAD_IMAGE_UNCHANGED); // Read the file
if (!imageSrc.data) // Check for invalid input
{
cout << "Could not open or find the image\n";
return 1;
}
cout << "Loaded " << fileName << " (" << imageSrc.channels() << " channels)\n";
imageSrc.convertTo(imageSrc, CV_32F, 1 / 255.0, 0.0);
int SliceSizeWidth = imageSrc.cols / 2;
int sliceShiftWidth = imageSrc.cols / 4;
int sliceWidthNumber = (imageSrc.cols / sliceShiftWidth) - 1;
int SliceSizeHeight = imageSrc.rows / 2;
int sliceShiftHeight = imageSrc.rows / 4;
int sliceHeightNumber = (imageSrc.rows / sliceShiftHeight) - 1;
for (int sliceIndexHeight = 0; sliceIndexHeight < sliceHeightNumber; sliceIndexHeight++)
{
for (int sliceIndexWidth = 0; sliceIndexWidth < sliceWidthNumber; sliceIndexWidth++)
{
Mat patchImage = imageSrc(Rect(sliceIndexWidth*sliceShiftWidth, sliceIndexHeight*sliceShiftHeight, SliceSizeWidth, SliceSizeHeight));
Mat patchImageCopy;
patchImage.copyTo(patchImageCopy); // Deep copy => data are contiguous in patchImageCopy
Mat imageBicubic;
resize(patchImageCopy, imageBicubic, Size(2 * patchImage.cols, 2 * patchImage.rows), INTER_CUBIC);
}
}
return 0;
}
My problem is that even if imageBicubic.channels() = 3, when I want to access the second and the third channels, I can't.
I used this line : cout << imageBicubic.at<float>(25,25,1) << endl; in order to see if the second channel was filled, and it seems that it was not (the dims of my image are 756*1200*3). The .exe just stop working. Without the cout, the .exe works fine.
Do I have something to add on the resize fonction to get a 3D Mat at the end ?
Thank you for your time !

Text detection from complex background

I have the following code which calculates the Daubechie 4 wavelet transformation images(LL,LH, HL, HH subbands) and energy features. In this paper is a tutorial about how to detect text from complex background, but I don't have any idea how to continue this. Could somebody help me, maybe to explain how I calculate wavelet energy histogram of an image or with ideas about how to implement what is on the paper?
#include <opencv2/highgui.hpp>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
#include <math.h>
#define h0 (1+sqrt(3))/(4*sqrt(2))
#define h1 (3+sqrt(3))/(4*sqrt(2))
#define h2 (3-sqrt(3))/(4*sqrt(2))
#define h3 (1-sqrt(3))/(4*sqrt(2))
#define g0 h3
#define g1 -h2
#define g2 h1
#define g3 -h0
using namespace std;
using namespace cv;
vector<Mat> wavelet(Mat im)
{
float a,b,c,d,e,f;
Mat im1, im2, im3, im4, im5, im6;
Mat imi=Mat::zeros(im.rows,im.cols,CV_8U);
im.copyTo(imi);
im.convertTo(im,CV_32F,1.0,0.0);
im1=Mat::zeros(im.rows/4,im.cols,CV_32F);
im2=Mat::zeros(im.rows/4,im.cols,CV_32F);
im3=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
im4=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
im5=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
im6=Mat::zeros(im.rows/4,im.cols/4,CV_32F);
for(int rcnt=0;rcnt+3<im.rows;rcnt+=4)
{
for(int ccnt=0;ccnt<im.cols;ccnt++)
{
a=im.at<float>(rcnt,ccnt);
b=im.at<float>(rcnt+1,ccnt);
c=im.at<float>(rcnt+2,ccnt);
d=im.at<float>(rcnt+3,ccnt);
e=(a*h0)+(b*h1)+(c*h2)+(d*h3);
f=(a*g0)+(b*g1)+(c*g2)+(d*g3);
int _rcnt=rcnt/4;
im1.at<float>(_rcnt,ccnt)=e;
im2.at<float>(_rcnt,ccnt)=f;
}
}
for(int rcnt=0;rcnt<im.rows/4;rcnt++)
{
for(int ccnt=0;ccnt+3<im.cols;ccnt+=4)
{
a=im1.at<float>(rcnt,ccnt);
b=im1.at<float>(rcnt,ccnt+1);
c=im1.at<float>(rcnt,ccnt+2);
d=im1.at<float>(rcnt,ccnt+3);
e=(a*h0)+(b*h1)+(c*h2)+(d*h3);
f=(a*g0)+(b*g1)+(c*g2)+(d*g3);
int _ccnt=ccnt/4;
im3.at<float>(rcnt,_ccnt)=e;
im4.at<float>(rcnt,_ccnt)=f;
}
}
for(int rcnt=0;rcnt<im.rows/4;rcnt++)
{
for(int ccnt=0;ccnt+3<im.cols;ccnt+=4)
{
a=im2.at<float>(rcnt,ccnt);
b=im2.at<float>(rcnt,ccnt+1);
c=im2.at<float>(rcnt,ccnt+2);
d=im2.at<float>(rcnt,ccnt+3);
e=(a*h0)+(b*h1)+(c*h2)+(d*h3);
f=(a*g0)+(b*g1)+(c*g2)+(d*g3);
int _ccnt=ccnt/4;
im5.at<float>(rcnt,_ccnt)=e;
im6.at<float>(rcnt,_ccnt)=f;
}
}
Mat LL = Mat(im3);
Mat LH = Mat(im4);
Mat HL = Mat(im5);
Mat HH = Mat(im6);
LL.convertTo(LL,CV_8U);
LH.convertTo(LH,CV_8U);
HL.convertTo(HL,CV_8U);
HH.convertTo(HH,CV_8U);
vector<Mat> elements;
elements.push_back(LL);
elements.push_back(LH);
elements.push_back(HL);
elements.push_back(HH);
return elements;
}
int main(int argc, char **argv)
{
Mat image = imread(argv[1],0);
vector<Mat> subbands = wavelet(image);
int rows = subbands[0].rows;
int cols = subbands[0].cols;
Mat energy(rows,cols,CV_8UC1);
for (int i=0;i<rows;i++)
{
for (int j=0;j<cols;j++)
{
int x=subbands[1].at<uchar>(i,j);
int y=subbands[2].at<uchar>(i,j);
int z=subbands[3].at<uchar>(i,j);
energy.at<uchar>(i,j)=sqrt(x*x+y*y+z*z);
}
}
imshow("energy",energy);
waitKey(0);
}

opencv error: assertion failed in cv::Mat::at file: mat.inl.hpp line 930

I have code for svm training phase. I use ms visual studio. I got error while executing below code:
#include <opencv/highgui.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
#include <fstream>
#include <ctime>
#include <stdio.h>
#include <math.h>
#include <opencv\cv.h>
#include <opencv2\objdetect\objdetect.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\imgcodecs.hpp>
#include <opencv2\core\core.hpp>
#include <vector>
#include <windows.h>
#include <atlstr.h>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <opencv2\core\core.hpp>
#include <opencv\cvaux.hpp>
using namespace cv;
using namespace cv::ml;
using namespace std;
void readCenters(cv::Mat&, const char *);
cv::Mat shuffleRows(const cv::Mat&,const cv::Mat&);
int CLUSTER_COUNT=5;//number of clusters
Mat train_data1;
Mat test_data;
void splitData(cv::Mat &data,cv::Mat &train_data1,cv::Mat &test_data)
{
int N=data.rows;
float ratio=0.7;
int train_data_length= N*ratio;
int test_data_length=N-train_data_length;
data(cv::Rect(0,0,data.cols,train_data_length)).copyTo(train_data1);
data(cv::Rect(0,train_data_length,data.cols,test_data_length)).copyTo(test_data);
cout<<"length : "<<train_data_length<<endl;
}
void readData(cv::Mat& data)
{
std::vector<const char *> filenames;
filenames.push_back("Data/ik147_1.txt");
filenames.push_back("Data/ik147_2.txt");
filenames.push_back("Data/ik147_3.txt");
filenames.push_back("Data/labels.txt");
std::string line;
std::vector<cv::Mat> raw_data(4);//= new std::vector<cv::Mat>(4);
int row;
double min,max;
for(int i =0;i<4;i++)
{
std::ifstream file( filenames[i] );
while( file>>row )
{
raw_data[i].push_back(row);
}
minMaxLoc(raw_data[i],&min,&max);
cout<<filenames[i]<<" min :"<<min<<", max :"<<max<<std::endl;
}
int N=raw_data[0].rows;
// cv::Mat data(N,3,CV_32FC1);
int columns_to_read=3;
data.create(N,columns_to_read,CV_32FC1);
for(int i=0;i<columns_to_read;i++)
{
raw_data[i](cv::Rect(0,0,1,N)).copyTo(data(cv::Rect(i,0,1,N)));
}
}
void computeLabelledData(cv:: Mat& data,cv::Mat &data_with_labels){
cv::Mat labels,centers;
cv::kmeans(data, CLUSTER_COUNT, labels,
cv::TermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0),
3, cv::KMEANS_PP_CENTERS, centers);
data_with_labels.create(data.rows,data.cols+1,CV_32FC1);
data.copyTo(data_with_labels(cv::Rect(0,0,data.cols,data.rows)));
labels.copyTo(data_with_labels(cv::Rect(data.cols,0,labels.cols,labels.rows)));
}
int main()
{
Mat data;
readData(data);
Mat data_with_labels,train_data_labels,test_data_labels;
computeLabelledData(data,data_with_labels);
splitData(data,train_data1,test_data);
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
int N=data.rows; //number of data points
int K=5; //number of labels
Mat train_data(train_data1.rows,train_data1.cols,CV_32F);
Mat labels;
int clusterCount=K;
int sampleCount = N;
Mat centers(5,2,CV_32FC1);
readCenters(centers,"centers.txt");
Point center;
center.x = 0;//rng_center.uniform(0, height);
center.y = 0;//rng_center.uniform(0, width);
// Set up training data
Mat labels_converted;
labels.convertTo(labels_converted, CV_32SC1);
Ptr<SVM> svm = SVM::create();
// edit: the params struct got removed,
// we use setter/getter now:
svm->setType(SVM::C_SVC);
// svm->setC(0.1);
svm->setKernel(SVM::LINEAR);
svm->setDegree(1./5);
svm->setGamma(100);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
// Train the SVM
//CvSVM svm;
svm->train(train_data, ROW_SAMPLE, labels_converted);
svm->save("svm_params.xml");
cout<<"svm parameters saved to : svm_params.xml"<<endl;
getchar();
}
void readCenters(cv::Mat &centers, const char * filename){
const int ROWS=5;
const int COLS=2;
cout<<"reading centers "<<filename<<endl;
float array[ROWS][COLS];
std::ifstream file( filename );
std::string line;
int row,col;
int i=0;
while( file>>row>>col )
{
centers.at<float>(i,0)=row;
centers.at<float>(i,1)=col;
i++;
}
}
cv::Mat shuffleRows(const cv::Mat &matrix,const cv::Mat &seeds)
{
cv::Mat output;
for (int cont = 0; cont < matrix.rows; cont++)
output.push_back(matrix.row((int)seeds.at<float>(cont,0)));
return output;
}
while executing this code, I got this error:
I able to read data from text files also centers.txt for define centers for kmeans. It is showing error at Mat::at in mat.inl.hpp file. I followed other references. Also tried to change datatypes from CV_32FC1 to CV_32F. But I cannot solve error.1
This error often happens when you are trying to access a pixel not inside your matrix. Also known as accessing a part of memory your program wasn't expecting to.
Take this example:
I have a matrix that is 10,10 and I try to access the 11,11 pixel. My program will crash and I will get the error that you are showing above. This can also happen even if I try to access 8,8 if I haven't loaded the image properly.
Take your code, wherever you are accessing a matrix could cause this issue, for instance this part of your code:
for(int i=0;i<columns_to_read;i++)
{
raw_data[i](cv::Rect(0,0,1,N)).copyTo(data(cv::Rect(i,0,1,N)));
}
You will need to step through it and see where it is crashing and then figure out what you are doing wrong.