OpenCV: Load multiple images and cluster them with bag of words - image

I am trying to cluster video frames abnormal and normal. I divided into frames as normal and abnormal with frames. I have two problem, I am not sure whether my approach is true or not and I got an unexpected error.
Please help me.
Error code: bowTrainer.add(features1);
My full code is as below:
// Bow.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/features2d/features2d.hpp"
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <windows.h>
#include "opencv2/ml/ml.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <limits>
#include <cstdio>
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
using std::vector;
using std::iostream;
int main()
{
initModule_nonfree();
Ptr<FeatureDetector> features = FeatureDetector::create("SIFT");
Ptr<DescriptorExtractor> descriptor = DescriptorExtractor::create("SIFT");
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("FlannBased");
//defining terms for bowkmeans trainer
TermCriteria tc(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 10, 0.001);
int dictionarySize = 100;
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(dictionarySize, tc, retries, flags);
BOWImgDescriptorExtractor bowDE(descriptor, matcher);
//**creating dictionary**//
Mat trainme(0, dictionarySize, CV_32FC1);
Mat labels(0, 1, CV_32FC1); //1d matrix with 32fc1 is requirement of normalbayesclassifier class
int i=0;
while(i<10)
{
char filename[255];
string n;
n=sprintf(filename, "C:\\Users\\Desktop\\New folder\\View_001\\frame_000%d.jpg",i);
Mat img = imread(filename, 0);
Mat features1;
vector<KeyPoint> keypoints;
descriptor->compute(img, keypoints, features1);
bowTrainer.add(features1);
Mat dictionary = bowTrainer.cluster();
bowDE.setVocabulary(dictionary);
Mat bowDescriptor;
bowDE.compute(img, keypoints, bowDescriptor);
trainme.push_back(bowDescriptor);
float label = 1.0;
labels.push_back(label);
i++;
}
int j=11;
while(j<21)
{
char filename2[255];
string n;
n=sprintf(filename2, "C:\\Users\\Desktop\\New folder\\View_001\\frame_000%d.jpg",j);
cout<<filename2;
Mat img2 = imread(filename2, 0);
Mat features2;
vector<KeyPoint> keypoints2;
descriptor->compute(img2, keypoints2, features2);
bowTrainer.add(features2);
Mat bowDescriptor2;
bowDE.compute(img2, keypoints2, bowDescriptor2);
trainme.push_back(bowDescriptor2);
float label = 2.0;
labels.push_back(label);
j++;
}
NormalBayesClassifier classifier;
classifier.train(trainme, labels);
//**classifier trained**//
//**now trying to predict using the same trained classifier, it should return 1.0**//
Mat tryme(0, dictionarySize, CV_32FC1);
Mat tryDescriptor;
Mat img3 = imread("C:\\Users\\Desktop\\New folder\\View_001\\frame_0121.jpg", 0);
vector<KeyPoint> keypoints3;
features->detect(img3, keypoints3);
bowDE.compute(img3, keypoints3, tryDescriptor);
tryme.push_back(tryDescriptor);
cout<<classifier.predict(tryme)<<endl;
waitKey(0);
system("PAUSE");
return 0;
}

Related

How to copy characters into string vector

Attempting to copy from a character vector to a string vector has been unsuccessful across multiple attempts at a solution
allocating memory to the vector prior to copying allows std::copy to work properly when placed at "OutputIterator result" (based on function template). I attempted:
std::copy(char1.begin(), char1.end(), v1.begin());
however, this was unsuccessful as well. using back_inserter returns error c2679 "binary '=': no operator found which takes a right-hand operand of type'char' (or there is no acceptable conversion).
input file is located here: https://adventofcode.com/2018/day/2
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iterator>
#include <cstdio>
int main() {
std::string field1;
std::string field2;
char characters;
std::vector<char>::iterator ptr;
std::vector<char>::iterator ptr2;
std::vector<char> char1;
std::vector<char> char2;
int size = 0;
std::ifstream inFile;
inFile.open("C:\\Users\\Administrator\\Desktop\\c++ files\\input2.txt");
if (!inFile) {
std::cout << "abort";
return 1;
}
while (inFile >> characters) { //read variables from input stream
char1.push_back(characters);
}
std::vector<std::string> v1(6500);
std::copy(char1.begin(), char1.end(), std::back_inserter(v1));
inFile.close();
return 0;
}
//26
expect vector v1 to hold values in vector char1. I am assuming the problem stems from the data type of v1 vs. char1, however, I have not been able to find a concrete solution. I do not want to read directly into a string vector; hence my current problem.
I am not sure what you try to achieve. Here few examples:
#include <string>
#include <vector>
int main()
{
std::string str1{ "Just for an example" }; // You can read it from a file
std::vector<std::string> vct_str1(32); // Lets say it has 32 std::string items
std::vector<std::string> vct_str2(32); // Lets say it has 32 std::string items
// **** A. Copy from std::string to std::vector<char>: ****
std::vector<char> vct_ch(str1.begin(), str1.end()); // On construction
// Or later: vct_ch.assign(str1.begin(), str1.end());
// **** B. Copy from std::vector<char> to std::string: ****
std::string str2(vct_ch.begin(), vct_ch.end()); // On construction
// Or later: str2.assign(vct_ch.begin(), vct_ch.end());
// **** C. Copy from std::vector<char> to std::vector<std::string>: ****
vct_str1[0].assign(vct_ch.begin(), vct_ch.end()); // Which is similar to B
// **** D. Source & Dest Types same as in Case-C But char per std::string: ****
int i = 0;
vct_str2.resize(vct_ch.size());
for (auto item : vct_ch)
vct_str2[i++] = item;
return 0;
}

Boost::spirit::qi - How do I build a parse rule that sets a property?

I'd like to build a rule that takes in a few parameters from a parsed line then sets a few as constant. Is that possible? An (invalid) example to illustrate what I'm trying to do is below. I think I'm using _r1 incorrectly here, but I'm not sure how to get at the right thing. Assume I don't want to just modify r before sending it into the parser.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_plus.hpp>
#include <boost/spirit/include/qi_sequence.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/phoenix/bind/bind_function.hpp>
#include <string>
using namespace boost::spirit::qi;
struct Sample
{
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
const rule<std::string::const_iterator, Sample()> AnythingAndOne = int_ >> eps[_r1.b = 1] >> eoi;
int main()
{
std::string z("3");
Sample r;
parse(z.begin(), z.end(), AnythingAndOne, r);
return 0;
}
Again, with reference to Boost Spirit: "Semantic actions are evil"? I'd avoid the semantic action.
You can directly synthesize a particular attribute value by using qi::attr:
Live On Coliru
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>
struct Sample {
int a;
int b;
};
BOOST_FUSION_ADAPT_STRUCT(Sample, a , b)
namespace qi = boost::spirit::qi;
int main()
{
std::string const z("3");
Sample r;
qi::rule<std::string::const_iterator, Sample()> AnythingAndOne
= qi::int_ >> qi::attr(1) >> qi::eoi;
if (parse(z.begin(), z.end(), AnythingAndOne, r))
std::cout << "Parsed: " << boost::fusion::as_vector(r) << "\n";
else
std::cout << "Parse failed\n";
}
Prints
Parsed: (3 1)

Why is C++ so much faster than C in this code?

My C code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char* a = (char*)malloc(200000);
for (int i = 0;i< 100000;i++){
strcat(a,"b");
}
printf("%s",a);
}
My C++ code is
#include <iostream>
int main(void){
std::string a = "";
for (int i = 0;i< 100000;i++){
¦ a+="b";
}
std::cout<<a;
}
On my machine, the C code runs in about 5 seconds, while on my machine, the C++ code runs in 0.025! seconds.
Now, the C code doesn't check for overflows, has no C++ overhead, classes and yet is quite a few magnitudes slower than my C++ code.
Using gcc/g++ 6.2.0 compiled with -O3 on Raspberry Pi.
#erwin was correct.
When I change my code to
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void mystrcat(char* src,char* dest,int lenSrc){
src[lenSrc]=dest[0];
}
int main(void){
char* a = (char*)malloc(200000);
for (int i = 0;i< 100000;i++){
mystrcat(a,"b",i);
}
a[100000] = 0;
printf("%s\n",a);
}
It takes about .012s to run (mostly printing the large screen).
Shlemiel's the painter's algorithm at work!

opencv undistort() doesn't work in vs2010 while works in Qtcreator

I found a problem in opencv2.4.8 undistort() in vs2010. It just show me one color image in "undist" window, while the same codes work fine in Qtcreator.
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
int main()
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
while(1)
{
Mat frame;
cap >> frame;
imshow("video",frame);
double cM[3][3] = {{610.12376,0,319.5}, {0,610.12376,239.5}, {0, 0, 1}};
Mat cameraMatrix = Mat(3, 3,CV_64F,cM);
double dM[5]={0.0681495,-0.128756,0,0,0.5857514};
Mat distCoeffs = Mat(8, 1, CV_64F,dM);
Mat undi=frame.clone();
undistort(frame,undi, cameraMatrix, distCoeffs);
imshow("undist",undi);
if ( (cvWaitKey(30) & 255) == 's' )
{
imwrite("test.jpg",undi);
}
else if ( (cvWaitKey(30) & 255) == 27 ) break;
}
cvWaitKey(0);
return 0;
}

Fail cvinvert on Iplimage or Mat

i need use CvInvert, but i have this problem:
OpenCV Error: Assertion failed (src.type() == dst.type() && src.rows
== dst.cols && src.cols == dst.rows) in cvInvert, file /opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/OpenCV-2.4.3/modules/core/src/lapack.cpp, line 1738 libc++abi.dylib: terminate called throwing an exception
This is Code:
#include <iostream>
#include <opencv/cv.h>
#include <stdio.h>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgproc/imgproc_c.h>
#include <opencv2/core/core_c.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, const char * argv[])
{
CvCapture* capture=cvCreateCameraCapture(0);
IplImage* originalImg;
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 640);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 480);
cvNamedWindow("Imagen");
while (true) {
originalImg=cvQueryFrame(capture);
cvFlip(originalImg,originalImg,3);
IplImage* Gray=cvCreateImage(cvGetSize(originalImg), IPL_DEPTH_8U, 1);
cvCvtColor(originalImg, Gray, CV_RGB2GRAY);
CvMat* Mat_tipo=cvCreateMat(originalImg->height, originalImg->width, CV_32F);
CvMat* Mat_img=cvGetMat(Gray,Mat_tipo);
CvMat* Matinvenrt=cvCreateMat(Mat_img->rows, Mat_img->cols, CV_32F);
cvInvert(Mat_img, Matinvenrt,CV_LU);
cvShowImage("Imagen", Mat_img);
// imshow("imagen", img);
cvReleaseMat(&Mat_img);
int id=cvWaitKey(27);
if (id==27) break;
}
}
What happen??, Have Cvinvert a bug??
Thank you.
Assertion failed (src.type() == dst.type()
it is clearly visible from your code that the Mat types are not the same for Mat_img and Matinvert
Are you sure you are inverting a square matrix?
I had a similar error and was because I was trying to invert a M-N matrix.

Resources