Related
First i want to say that i am trying to solve Palindrome Number problem on LeetCode using dart, of course
https://leetcode.com/problems/palindrome-number/
So far I have tried total 6 different method to solve the problem.
And am not very happy to say that all of them leading to time limit exceeded error on LeetCode.. Solutions are perfectly working on terminal because of the less test cases but when submit, and it tried on large number it ends up error.
My 6 solutions based on different classes.each class contain their own implemented solution..
I dont know if the while loop in dart is slow or something wrong with the leetcode
class A {
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
double divisor = 1;
while (x / divisor >= 10) {
divisor *= 10;
}
while (x != 0) {
if ((x / divisor).truncate() != (x % 10).floor()) {
return false;
}
x %= divisor.toInt();
x = (x / 10).floor();
divisor /= 100;
}
return true;
}
}
class B {
bool isPalindrome(int x) {
if (x < 0 || (x % 10 == 0 && x != 0)) {
return false;
}
int revNum = 0;
while (x > revNum) {
revNum = revNum * 10 + x % 10;
x = (x / 10).floor();
}
return (x == revNum || x == revNum / 10);
}
}
class C {
bool isPalindrome(int x) {
if (x < 0) {
return false;
}
int y = 0;
int xx = x;
if (xx > 0) {
y = y * 10 + xx % 10;
xx = (xx / 10).floor();
}
return (y != x);
}
// while (xx > 0) {
// y = y * 10 + xx % 10;
// xx = (xx / 10).floor();
// }
}
class D {
bool isPalindrome(int x) {
if (x.isNegative) return false;
final list = convert(x);
for (var i = 0; i < (list.length ~/ 2); i++) {
if (list[i] != list[list.length - 1 - i]) return false;
}
return true;
}
List convert(int x) {
final List<int> list = <int>[];
while (x > 0) {
list.add(x % 10);
x = x ~/ 10;
}
return list;
}
}
class F {
bool isPalindrome(int x) {
if (x.isNegative) return false;
if (x == 0) return true;
if (x % 10 == 0) return false;
var reverted = 0, iter = x;
while (iter > 0) {
reverted = reverted * 10;
reverted += iter % 10;
iter = iter ~/ 10;
}
return reverted == x;
}
}
class G {
bool isPalindrome(int x) {
if (x.isNegative) return false;
var tens = 10;
while (tens < x) tens *= 10;
tens = tens ~/ 10;
while (x > 10) {
var lastDigit = x % 10;
var firstDigit = x ~/ tens;
if (lastDigit != firstDigit) return false;
x -= firstDigit * tens;
x = x ~/ 10;
tens = tens ~/ 100;
}
return true;
}
}
I'm pretty sure the leetcode site has a problem here.
I don't know what they're using their time on, but it seems impossible to get a correct result without a timeout.
My attempted solutions are:
class Solution2 {
// No intermediate allocations, only number operations.
bool isPalindrome(int x) {
if (x < 0) return false;
if (x < 10) return true;
int r = 0;
do {
var d = x.remainder(10);
x = x ~/ 10;
if (r == x) return true; // Odd length number
r = r * 10 + d;
if (r == x) return true; // Even length number
if (r == 0) return false; // Trailing zero
} while (r < x);
return false;
}
}
class Solution3 {
// Just do toString and check that it's a palindrome.
// Integer.toString is heavily optimized already.
bool isPalindrome(int x) {
if (x < 0) return false;
if (x < 10) return true;
var s = x.toString();
for (var i = 0, j = s.length - 1; i < j; i++, j--) {
if (s.codeUnitAt(i) != s.codeUnitAt(j)) return false;
}
return true;
}
}
If those are not fast enough, I seriously doubt anything will be.
I even considered whether repeatedly dividing by 10 was incredibly slow for some reason, so I switched to dividing by 100 instead, which should halve the divisions.
class Solution {
// Minimize divisions by dividing by 100, and do lookup for the digits.
static const digits =[
0, 0, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 8, 0, 9,
1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9,
2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 2, 5, 2, 6, 2, 7, 2, 8, 2, 9,
3, 0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3, 6, 3, 7, 3, 8, 3, 9,
4, 0, 4, 1, 4, 2, 4, 3, 4, 4, 4, 5, 4, 6, 4, 7, 4, 8, 4, 9,
5, 0, 5, 1, 5, 2, 5, 3, 5, 4, 5, 5, 5, 6, 5, 7, 5, 8, 5, 9,
6, 0, 6, 1, 6, 2, 6, 3, 6, 4, 6, 5, 6, 6, 6, 7, 6, 8, 6, 9,
7, 0, 7, 1, 7, 2, 7, 3, 7, 4, 7, 5, 7, 6, 7, 7, 7, 8, 7, 9,
8, 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7, 8, 8, 8, 9,
9, 0, 9, 1, 9, 2, 9, 3, 9, 4, 9, 5, 9, 6, 9, 7, 9, 8, 9, 9,
];
bool isPalindrome(int x) {
if (x < 0) return false;
if (x < 10) return true;
int r = 0;
do {
var d = x.remainder(100);
x = x ~/ 100;
var d1 = digits[d * 2];
var d2 = digits[d * 2 + 1];
if (r == x && d1 == d2) return true; // Even length number
if (r == x * 10 + d1) return true; // Odd length number.
r = r * 10 + d2;
if (r == 0) return false; // Trailing zero
if (r == x) return true; // Odd length number
r = r * 10 + d1;
if (r == x) return true; // Even length number
} while (r < x);
return false;
}
}
Still times out.
I'm trying to use the Bollinger Bands to get a signal to open orders buy or sell. To do this, I am trying to test if candle[2] and candle[1] are closing above or below MODE_UPPER and MODE_LOWER of iBands to open the order. The problem is that the order are opening next to MODE_MAIN instead of MODE_UPPER or MODE_LOWER and I don't know why it happening.
How could I do this ?
Trying
//return true if has a signal to open order
bool bollingerBandScalper(int bs){
int _candle = 0;
int _period = 14;
//double _main = iBands(_Symbol, _Period, _period, 2, 0, PRICE_CLOSE, MODE_MAIN, _candle + 1);
double LowerBB = iBands(_Symbol, _Period, _period, 2, 0, PRICE_CLOSE, MODE_LOWER, _candle + 1);
double UpperBB = iBands(_Symbol, _Period, _period, 2, 0, PRICE_CLOSE, MODE_UPPER, _candle + 1);
double PrevLowerBB = iBands(_Symbol, _Period, _period, 2, 0, PRICE_CLOSE, MODE_LOWER, _candle + 2);
double PrevUpperBB = iBands(_Symbol, _Period, _period, 2, 0, PRICE_CLOSE, MODE_UPPER, _candle + 2);
//buy signal
if(bs == OP_BUY){
if((Close[_candle + 2] > PrevLowerBB) && (Close[_candle + 1] > LowerBB)){
return true;
}
}
//sell signal
if(bs == OP_SELL){
if((Close[_candle + 2] > PrevUpperBB) && (Close[_candle + 1] > UpperBB)){
return true;
}
}
return false;
}
I think you've made a mistake to find where price closes above/below BB Bands.
I made some changes in your code. You can test it:
//return true if has a signal to open order
bool bollingerBandScalper(int type,int period,int shift)
{
double LowerBB = iBands(_Symbol,_Period,period,2.0,0,PRICE_CLOSE,MODE_LOWER,shift+1);
double UpperBB = iBands(_Symbol,_Period,period,2.0,0,PRICE_CLOSE,MODE_UPPER,shift+1);
double PrevLowerBB = iBands(_Symbol,_Period,period,2,0,PRICE_CLOSE,MODE_LOWER,shift+2);
double PrevUpperBB = iBands(_Symbol,_Period,period,2,0,PRICE_CLOSE,MODE_UPPER,shift+2);
//buy signal
if(type==OP_BUY && Close[shift+2]>PrevLowerBB && Close[shift+1]<LowerBB) return true;
//sell signal
if(type==OP_SELL && Close[shift+2]<PrevUpperBB && Close[shift+1]>UpperBB) return true;
return false;
}
Func support("support");
Expr left_x = clamp(x, 0, left_buffer.width() / 4);
RDom scan_left(0, left_buffer.width() / 4, 0, left_buffer.height());
scan_left.where(scan_left.x != left_x && scan_left.y != y);
support(x, y) = argmin(abs(output_x(left_x, y) - output_x(scan_left.x, scan_left.y)) + abs(output_y(left_x, y) - output_y(scan_left.x, scan_left.y)));
Expr center_x = clamp(x, left_buffer.width() / 4, left_buffer.width() * 3/4);
RDom scan_center(-left_buffer.width() / 4, left_buffer.width() / 2, 0, left_buffer.height());
scan_center.where(scan_center.x != 0 && scan_center.y != 0);
support(x, y) = argmin(abs(output_x(center_x, y) - output_x(center_x + scan_center.x, scan_center.y)) + abs(output_y(center_x, scan_center.y) - output_y(center_x + scan_center.x, scan_center.y)));
Expr right_x = clamp(x, left_buffer.width() * 3/4, left_buffer.width());
RDom scan_right(left_buffer.width() * 3/4, left_buffer.width() / 4, 0, left_buffer.height());
scan_right.where(scan_right.x != right_x && scan_right.y != y);
support(x, y) = argmin(abs(output_x(right_x, y) - output_x(scan_right.x, scan_right.y)) + abs(output_y(right_x, y) - output_y(scan_right.x, scan_right.y)));
support.trace_stores();
Realization r = support.realize(left_buffer.width(), left_buffer.height());
The function "support" should be computed differently depending on the x value. For x = [0, width/4] compute it according to the first definition, for x = [width/4, width * 3/4] compute it according to the second definition, and for x = [width*3/4, width] compute it according the third definition. I would think that putting the boundary conditions with respect to those update definitions and then realizing over the whole buffer would do the trick. Right now though, the previous definitions are being overwritten. Since this doesn't seem to work, I would think of doing three realizations but that seems inelegant since we're talking about just one image. Is it possible to achieve the result in a single realization, or must I break into three realizations?
I tried RDoms too:
Func support("support");
support(x, y) = Tuple(i32(0), i32(0), f32(0));
RDom left_x(0, left_buffer.width() / 4);
RDom scan_left(0, left_buffer.width() / 4, 0, left_buffer.height());
scan_left.where(scan_left.x != left_x && scan_left.y != y);
support(left_x, y) = argmin(scan_left, abs(output_x(left_x, y) - output_x(scan_left.x, scan_left.y)) + abs(output_y(left_x, y) - output_y(scan_left.x, scan_left.y)));
RDom center_x(left_buffer.width() / 4, left_buffer.width() / 2);
RDom scan_center(-left_buffer.width() / 4, left_buffer.width() / 2, 0, left_buffer.height());
scan_center.where(scan_center.x != 0 && scan_center.y != 0);
support(center_x, y) = argmin(scan_center, abs(output_x(center_x, y) - \
output_x(center_x + scan_center.x, scan_center.y)) + abs(output_y(center_x, scan_center.y) - \
output_y(center_x + scan_center.x, scan_center.y)));
RDom right_x(left_buffer.width() * 3/4, left_buffer.width() / 4);
RDom scan_right(left_buffer.width() * 3/4, left_buffer.width() / 4, 0, left_buffer.height());
scan_right.where(scan_right.x != right_x && scan_right.y != y);
support(right_x, y) = argmin(scan_right, abs(output_x(right_x, y) - output_x(scan_right.x, scan_right.y)) + abs(output_y(right_x, y) - output_y(scan_right.x, scan_right.y)));
support.compute_root();
support.trace_stores();
Realization r_left = support.realize(left_buffer.width(), left_buffer.height());
but this code gives errors in the following lines:
scan_left.where(scan_left.x != left_x && scan_left.y != y);
...
scan_right.where(scan_right.x != right_x && scan_right.y != y);
A simple way to solve this problem would be to use Halide's select method (example given here). Something like this should work:
Func support("support");
Expr left_x = clamp(x, 0, left_buffer.width() / 4);
RDom scan_left(0, left_buffer.width() / 4, 0, left_buffer.height());
scan_left.where(scan_left.x != left_x && scan_left.y != y);
Expr first = argmin(abs(output_x(left_x, y) - output_x(scan_left.x, scan_left.y)) + abs(output_y(left_x, y) - output_y(scan_left.x, scan_left.y)));
Expr center_x = clamp(x, left_buffer.width() / 4, left_buffer.width() * 3/4);
RDom scan_center(-left_buffer.width() / 4, left_buffer.width() / 2, 0, left_buffer.height());
scan_center.where(scan_center.x != 0 && scan_center.y != 0);
Expr second = argmin(abs(output_x(center_x, y) - output_x(center_x + scan_center.x, scan_center.y)) + abs(output_y(center_x, scan_center.y) - output_y(center_x + scan_center.x, scan_center.y)));
Expr right_x = clamp(x, left_buffer.width() * 3/4, left_buffer.width());
RDom scan_right(left_buffer.width() * 3/4, left_buffer.width() / 4, 0, left_buffer.height());
scan_right.where(scan_right.x != right_x && scan_right.y != y);
Expr third = argmin(abs(output_x(right_x, y) - output_x(scan_right.x, scan_right.y)) + abs(output_y(right_x, y) - output_y(scan_right.x, scan_right.y)));
int width = left_buffer.width();
# select based on x value
support(x, y) = select(x < width / 4, first, x < width * 3 / 4, second, third);
support.trace_stores();
Realization r = support.realize(left_buffer.width(), left_buffer.height());
`
Hello I want some help with this little piece of code. Could you tell me what is wrong with it? Thank you.
if(Cross(15, iMA(NULL, PERIOD_H1, 3, 0, MODE_SMA, PRICE_CLOSE, 0) < iMA(NULL, PERIOD_H1, 80, 0, MODE_SMA, PRICE_CLOSE, 0))
&& if(Cross (16, iMA(NULL, PERIOD_M1, 3, 0, MODE_SMA, PRICE_CLOSE, 0) > iMA(NULL, PERIOD_M1, 20, 0, MODE_SMA, PRICE_CLOSE, 0)) //Moving Average crosses above Moving Average
//Moving Average crosses below Moving Average
))
{
RefreshRates();
price = Ask;
if(IsTradeAllowed())
{
ticket = myOrderSend(OP_BUY, price, TradeSize, "");
if(ticket <= 0) return;
}
else //not autotrading => only send alert
myAlert("order", "");
}
if(Cross(15,iMA(NULL,PERIOD_H1,3,0,MODE_SMA,PRICE_CLOSE,0) <
iMA(NULL,PERIOD_H1,80,0,MODE_SMA,PRICE_CLOSE,0)) &&
Cross(16,iMA(NULL,PERIOD_M1,3,0,MODE_SMA,PRICE_CLOSE,0) >
iMA(NULL,PERIOD_M1,20,0,MODE_SMA,PRICE_CLOSE,0)))
//Moving Average crosses above Moving Average
{
RefreshRates();
price = Ask;
if(IsTradeAllowed())
{
ticket = myOrderSend(OP_BUY, price, TradeSize, "");
if(ticket <= 0) return;
}
else //not autotrading => only send alert
myAlert("order", "");
}
}
The OpenCV docs give the following SVM kernel type example:
A comparison of different kernels on the following 2D test case with four classes. Four SVM::C_SVC SVMs have been trained (one against rest) with auto_train. Evaluation on three different kernels (SVM::CHI2, SVM::INTER, SVM::RBF). The color depicts the class with max score. Bright means max-score > 0, dark means max-score < 0.
Where can I find the sample code that generates this example?
Specifically, the SVM predict() method presumably returns a label value and not a max-score. How can it return a max-score?
Note that the quote states that it uses SVM::C_SVC which is a classification, not a regression, type.
You can get the score with 2-class SVM, and if you pass RAW_OUTPUT to predict:
// svm.cpp, SVMImpl::predict(...) , line 1917
bool returnDFVal = (flags & RAW_OUTPUT) != 0;
// svm.cpp, PredictBody::operator(), line 1896,
float result = returnDFVal && class_count == 2 ?
(float)sum : (float)(svm->class_labels.at<int>(k));
Then you need to train 4 different 2 class SVM, one against rest.
These are the result I get on these samples:
INTER with trainAuto
CHI2 with trainAuto
RBF with train (C = 0.1, gamma = 0.001) (trainAuto overfits in this case)
Here is the code. You can enable trainAuto with AUTO_TRAIN_ENABLED boolean variable, and you can set the KERNEL as well as images dimensions, etc.
#include <opencv2/opencv.hpp>
#include <vector>
#include <algorithm>
using namespace std;
using namespace cv;
using namespace cv::ml;
int main()
{
const int WIDTH = 512;
const int HEIGHT = 512;
const int N_SAMPLES_PER_CLASS = 10;
const float NON_LINEAR_SAMPLES_RATIO = 0.1;
const int KERNEL = SVM::CHI2;
const bool AUTO_TRAIN_ENABLED = false;
int N_NON_LINEAR_SAMPLES = N_SAMPLES_PER_CLASS * NON_LINEAR_SAMPLES_RATIO;
int N_LINEAR_SAMPLES = N_SAMPLES_PER_CLASS - N_NON_LINEAR_SAMPLES;
vector<Scalar> colors{Scalar(255,0,0), Scalar(0,255,0), Scalar(0,0,255), Scalar(0,255,255)};
vector<Vec3b> colorsv{ Vec3b(255, 0, 0), Vec3b(0, 255, 0), Vec3b(0, 0, 255), Vec3b(0, 255, 255) };
vector<Vec3b> colorsv_shaded{ Vec3b(200, 0, 0), Vec3b(0, 200, 0), Vec3b(0, 0, 200), Vec3b(0, 200, 200) };
Mat1f data(4 * N_SAMPLES_PER_CLASS, 2);
Mat1i labels(4 * N_SAMPLES_PER_CLASS, 1);
RNG rng(0);
////////////////////////
// Set training data
////////////////////////
// Class 1
Mat1f class1 = data.rowRange(0, 0.5 * N_LINEAR_SAMPLES);
Mat1f x1 = class1.colRange(0, 1);
Mat1f y1 = class1.colRange(1, 2);
rng.fill(x1, RNG::UNIFORM, Scalar(1), Scalar(WIDTH));
rng.fill(y1, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT / 8));
class1 = data.rowRange(0.5 * N_LINEAR_SAMPLES, 1 * N_LINEAR_SAMPLES);
x1 = class1.colRange(0, 1);
y1 = class1.colRange(1, 2);
rng.fill(x1, RNG::UNIFORM, Scalar(1), Scalar(WIDTH));
rng.fill(y1, RNG::UNIFORM, Scalar(7*HEIGHT / 8), Scalar(HEIGHT));
class1 = data.rowRange(N_LINEAR_SAMPLES, 1 * N_SAMPLES_PER_CLASS);
x1 = class1.colRange(0, 1);
y1 = class1.colRange(1, 2);
rng.fill(x1, RNG::UNIFORM, Scalar(1), Scalar(WIDTH));
rng.fill(y1, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
// Class 2
Mat1f class2 = data.rowRange(N_SAMPLES_PER_CLASS, N_SAMPLES_PER_CLASS + N_LINEAR_SAMPLES);
Mat1f x2 = class2.colRange(0, 1);
Mat1f y2 = class2.colRange(1, 2);
rng.fill(x2, RNG::NORMAL, Scalar(3 * WIDTH / 4), Scalar(WIDTH/16));
rng.fill(y2, RNG::NORMAL, Scalar(HEIGHT / 2), Scalar(HEIGHT/4));
class2 = data.rowRange(N_SAMPLES_PER_CLASS + N_LINEAR_SAMPLES, 2 * N_SAMPLES_PER_CLASS);
x2 = class2.colRange(0, 1);
y2 = class2.colRange(1, 2);
rng.fill(x2, RNG::UNIFORM, Scalar(1), Scalar(WIDTH));
rng.fill(y2, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
// Class 3
Mat1f class3 = data.rowRange(2 * N_SAMPLES_PER_CLASS, 2 * N_SAMPLES_PER_CLASS + N_LINEAR_SAMPLES);
Mat1f x3 = class3.colRange(0, 1);
Mat1f y3 = class3.colRange(1, 2);
rng.fill(x3, RNG::NORMAL, Scalar(WIDTH / 4), Scalar(WIDTH/8));
rng.fill(y3, RNG::NORMAL, Scalar(HEIGHT / 2), Scalar(HEIGHT/8));
class3 = data.rowRange(2*N_SAMPLES_PER_CLASS + N_LINEAR_SAMPLES, 3 * N_SAMPLES_PER_CLASS);
x3 = class3.colRange(0, 1);
y3 = class3.colRange(1, 2);
rng.fill(x3, RNG::UNIFORM, Scalar(1), Scalar(WIDTH));
rng.fill(y3, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
// Class 4
Mat1f class4 = data.rowRange(3 * N_SAMPLES_PER_CLASS, 3 * N_SAMPLES_PER_CLASS + 0.5 * N_LINEAR_SAMPLES);
Mat1f x4 = class4.colRange(0, 1);
Mat1f y4 = class4.colRange(1, 2);
rng.fill(x4, RNG::NORMAL, Scalar(WIDTH / 2), Scalar(WIDTH / 16));
rng.fill(y4, RNG::NORMAL, Scalar(HEIGHT / 4), Scalar(HEIGHT / 16));
class4 = data.rowRange(3 * N_SAMPLES_PER_CLASS + 0.5 * N_LINEAR_SAMPLES, 3 * N_SAMPLES_PER_CLASS + N_LINEAR_SAMPLES);
x4 = class4.colRange(0, 1);
y4 = class4.colRange(1, 2);
rng.fill(x4, RNG::NORMAL, Scalar(WIDTH / 2), Scalar(WIDTH / 16));
rng.fill(y4, RNG::NORMAL, Scalar(3 * HEIGHT / 4), Scalar(HEIGHT / 16));
class4 = data.rowRange(3 * N_SAMPLES_PER_CLASS + N_LINEAR_SAMPLES, 4 * N_SAMPLES_PER_CLASS);
x4 = class4.colRange(0, 1);
y4 = class4.colRange(1, 2);
rng.fill(x4, RNG::UNIFORM, Scalar(1), Scalar(WIDTH));
rng.fill(y4, RNG::UNIFORM, Scalar(1), Scalar(HEIGHT));
// Labels
labels.rowRange(0*N_SAMPLES_PER_CLASS, 1*N_SAMPLES_PER_CLASS).setTo(1);
labels.rowRange(1*N_SAMPLES_PER_CLASS, 2*N_SAMPLES_PER_CLASS).setTo(2);
labels.rowRange(2*N_SAMPLES_PER_CLASS, 3*N_SAMPLES_PER_CLASS).setTo(3);
labels.rowRange(3*N_SAMPLES_PER_CLASS, 4*N_SAMPLES_PER_CLASS).setTo(4);
// Draw training data
Mat3b samples(HEIGHT, WIDTH, Vec3b(0,0,0));
for (int i = 0; i < labels.rows; ++i)
{
circle(samples, Point(data(i, 0), data(i, 1)), 3, colors[labels(i,0) - 1], CV_FILLED);
}
//////////////////////////
// SVM
//////////////////////////
// SVM label 1
Ptr<SVM> svm1 = SVM::create();
svm1->setType(SVM::C_SVC);
svm1->setKernel(KERNEL);
Mat1i labels1 = (labels != 1) / 255;
if (AUTO_TRAIN_ENABLED)
{
Ptr<TrainData> td1 = TrainData::create(data, ROW_SAMPLE, labels1);
svm1->trainAuto(td1);
}
else
{
svm1->setC(0.1);
svm1->setGamma(0.001);
svm1->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, (int)1e7, 1e-6));
svm1->train(data, ROW_SAMPLE, labels1);
}
// SVM label 2
Ptr<SVM> svm2 = SVM::create();
svm2->setType(SVM::C_SVC);
svm2->setKernel(KERNEL);
Mat1i labels2 = (labels != 2) / 255;
if (AUTO_TRAIN_ENABLED)
{
Ptr<TrainData> td2 = TrainData::create(data, ROW_SAMPLE, labels2);
svm2->trainAuto(td2);
}
else
{
svm2->setC(0.1);
svm2->setGamma(0.001);
svm2->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, (int)1e7, 1e-6));
svm2->train(data, ROW_SAMPLE, labels2);
}
// SVM label 3
Ptr<SVM> svm3 = SVM::create();
svm3->setType(SVM::C_SVC);
svm3->setKernel(KERNEL);
Mat1i labels3 = (labels != 3) / 255;
if (AUTO_TRAIN_ENABLED)
{
Ptr<TrainData> td3 = TrainData::create(data, ROW_SAMPLE, labels3);
svm3->trainAuto(td3);
}
else
{
svm3->setC(0.1);
svm3->setGamma(0.001);
svm3->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, (int)1e7, 1e-6));
svm3->train(data, ROW_SAMPLE, labels3);
}
// SVM label 4
Ptr<SVM> svm4 = SVM::create();
svm4->setType(SVM::C_SVC);
svm4->setKernel(KERNEL);
Mat1i labels4 = (labels != 4) / 255;
if (AUTO_TRAIN_ENABLED)
{
Ptr<TrainData> td4 = TrainData::create(data, ROW_SAMPLE, labels4);
svm4->trainAuto(td4);
}
else
{
svm4->setC(0.1);
svm4->setGamma(0.001);
svm4->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, (int)1e7, 1e-6));
svm4->train(data, ROW_SAMPLE, labels4);
}
//////////////////////////
// Show regions
//////////////////////////
Mat3b regions(HEIGHT, WIDTH);
Mat1f R(HEIGHT, WIDTH);
Mat1f R1(HEIGHT, WIDTH);
Mat1f R2(HEIGHT, WIDTH);
Mat1f R3(HEIGHT, WIDTH);
Mat1f R4(HEIGHT, WIDTH);
for (int r = 0; r < HEIGHT; ++r)
{
for (int c = 0; c < WIDTH; ++c)
{
Mat1f sample = (Mat1f(1,2) << c, r);
vector<float> responses(4);
responses[0] = svm1->predict(sample, noArray(), StatModel::RAW_OUTPUT);
responses[1] = svm2->predict(sample, noArray(), StatModel::RAW_OUTPUT);
responses[2] = svm3->predict(sample, noArray(), StatModel::RAW_OUTPUT);
responses[3] = svm4->predict(sample, noArray(), StatModel::RAW_OUTPUT);
int best_class = distance(responses.begin(), max_element(responses.begin(), responses.end()));
float best_response = responses[best_class];
// View responses for each SVM, and the best responses
R(r,c) = best_response;
R1(r, c) = responses[0];
R2(r, c) = responses[1];
R3(r, c) = responses[2];
R4(r, c) = responses[3];
if (best_response >= 0) {
regions(r, c) = colorsv[best_class];
}
else {
regions(r, c) = colorsv_shaded[best_class];
}
}
}
imwrite("svm_samples.png", samples);
imwrite("svm_x.png", regions);
imshow("Samples", samples);
imshow("Regions", regions);
waitKey();
return 0;
}