I am using visual studio 15 and working in opencv 3.0 ,i am getting access violation error in my code and even this function is not working with sample code given in opencv.
#include"stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <math.h>
#include <iostream>
using namespace cv;
using namespace std;
static void help()
{
cout
<< "\nThis program illustrates the use of findContours and drawContours\n"
<< "The original image is put up along with the image of drawn contours\n"
<< "Usage:\n"
<< "./contours2\n"
<< "\nA trackbar is put up which controls the contour level from -3 to 3\n"
<< endl;
}
const int w = 500;
int levels = 3;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
static void on_trackbar(int, void*)
{
Mat cnt_img = Mat::zeros(w, w, CV_8UC3);
int _levels = levels - 3;
drawContours(cnt_img, contours, _levels <= 0 ? 3 : -1, Scalar(128, 255, 255),
3, LINE_AA, hierarchy, std::abs(_levels));
imshow("contours", cnt_img);
}
int main(int argc, char**)
{
Mat img = Mat::zeros(w, w, CV_8UC1);
if (argc > 1)
{
help();
return -1;
}
//Draw 6 faces
for (int i = 0; i < 6; i++)
{
int dx = (i % 2) * 250 - 30;
int dy = (i / 2) * 150;
const Scalar white = Scalar(255);
const Scalar black = Scalar(0);
if (i == 0)
{
for (int j = 0; j <= 10; j++)
{
double angle = (j + 5)*CV_PI / 21;
line(img, Point(cvRound(dx + 100 + j * 10 - 80 * cos(angle)),
cvRound(dy + 100 - 90 * sin(angle))),
Point(cvRound(dx + 100 + j * 10 - 30 * cos(angle)),
cvRound(dy + 100 - 30 * sin(angle))), white, 1, 8, 0);
}
}
ellipse(img, Point(dx + 150, dy + 100), Size(100, 70), 0, 0, 360, white, -1, 8, 0);
ellipse(img, Point(dx + 115, dy + 70), Size(30, 20), 0, 0, 360, black, -1, 8, 0);
ellipse(img, Point(dx + 185, dy + 70), Size(30, 20), 0, 0, 360, black, -1, 8, 0);
ellipse(img, Point(dx + 115, dy + 70), Size(15, 15), 0, 0, 360, white, -1, 8, 0);
ellipse(img, Point(dx + 185, dy + 70), Size(15, 15), 0, 0, 360, white, -1, 8, 0);
ellipse(img, Point(dx + 115, dy + 70), Size(5, 5), 0, 0, 360, black, -1, 8, 0);
ellipse(img, Point(dx + 185, dy + 70), Size(5, 5), 0, 0, 360, black, -1, 8, 0);
ellipse(img, Point(dx + 150, dy + 100), Size(10, 5), 0, 0, 360, black, -1, 8, 0);
ellipse(img, Point(dx + 150, dy + 150), Size(40, 10), 0, 0, 360, black, -1, 8, 0);
ellipse(img, Point(dx + 27, dy + 100), Size(20, 35), 0, 0, 360, white, -1, 8, 0);
ellipse(img, Point(dx + 273, dy + 100), Size(20, 35), 0, 0, 360, white, -1, 8, 0);
}
//show the faces
namedWindow("image", 1);
imshow("image", img);
//Extract the contours so that
//vector<vector<Point> > contours0;
vector<cv::Mat> coutours;
findContours(img, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
contours.resize(contours.size());
for (size_t k = 0; k < contours.size(); k++)
approxPolyDP(Mat(contours[k]), contours[k], 3, true);
namedWindow("contours", 1);
createTrackbar("levels+3", "contours", &levels, 7, on_trackbar);
on_trackbar(0, 0);
waitKey();
return 0;
}
I am using x64 architecture and linked all the library .lib along with d.lib(debug library).
I think the problem comes from your "contours" variable. You're declaring it as a vector<cv::Mat>, but the contours are not represented as a matrix, but rather as a series of points.
Look at this example : http://docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html
They declare the contours as vector<vector<Point> > contours;
Look also at the declaration of the function (http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours), the paramater contour is defined as : contours – Detected contours. Each contour is stored as a vector of points.
Related
// I used cvtColor, inRange , bitwise_and, GaussianBlur, Canny functions before.
vector<vector<Point>> contours; // to store contours
vector<Vec4i> hierarchy;
int mode = RETR_CCOMP;
//int module = CHAIN_APPROX_NONE;
//int module = CHAIN_APPROX_SIMPLE;
//int module = CHAIN_APPROX_TC89_L1;
int module = CHAIN_APPROX_TC89_KCOS;
findContours(img_edge, contours, hierarchy, mode, module);
sort(contours.begin(), contours.end(), compareContourAreas);
drawContours(image, contours, -1, Scalar(255, 0, 0), 1);
imshow("ContourImage", image);
vector<Point> contours_approx;
for (int i = 0; i < 5; i++)
{
double length = arcLength(contours[i], true);
approxPolyDP(contours[i], contours_approx, 0.1 * length, true);
if (contours_approx.size() == 4)
{
break;
}
contours_approx.clear();
}
for (Point i : contours_approx)
{
cout << i << endl; // to check coordinate of vertex
}
drawContours(contour2, vector<vector<Point>>(1, contours_approx), -1, Scalar(0, 0, 255), 1);
// to find vertex
circle(contour2, Point(x0, y0), 5, Scalar(255, 0, 0), -1, -1, 0); // blue
circle(contour2, Point(x1, y1), 5, Scalar(0, 255, 0), -1, -1, 0); // green
circle(contour2, Point(x2, y2), 5, Scalar(0, 0, 255), -1, -1, 0); // red
circle(contour2, Point(x3, y3), 5, Scalar(255, 255, 255), -1, -1, 0); // white
imshow("contour2", contour2);
In first, second picture, there is a result that I want. There are circles at vertex of rectangle.
But in third, fourth picture,I modified the angle of cuboid, and there is a result that I don't want. Circles were in very small rectangle above the large rectangle.
In first, third picture I guess that findContours function works well. And I guess that there is a problem in approxPolyDP function.
To locate circle in the largest rectangle, what should I have to do?
Thanks for your answer
I have just started my learning on SVM using C++ OpenCV and was referring to the SVM documentation here. I wanted to try out the sample source code from the link to get familiar with it first but I couldn't run the sample source code. It returns the error :
Error 1 error C2065: 'CvSVMParams' : undeclared identifier
I'm using Visual Studio 2012 with OpenCV 3.0.0. The setup process should be correct as all other codes are working well except this.
A lot of things changed from OpenCV 2.4 to OpenCV 3.0. Among others, the machine learning module, which isn't backward compatible.
This is the OpenCV tutorial code for the SVM, update for OpenCV 3.0:
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
using namespace cv;
using namespace cv::ml;
int main(int, char**)
{
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
// Set up training data
int labels[4] = { 1, -1, -1, -1 };
Mat labelsMat(4, 1, CV_32SC1, labels);
float trainingData[4][2] = { { 501, 10 }, { 255, 10 }, { 501, 255 }, { 10, 501 } };
Mat trainingDataMat(4, 2, CV_32FC1, trainingData);
// Set up SVM's parameters
Ptr<SVM> svm = SVM::create();
svm->setType(SVM::C_SVC);
svm->setKernel(SVM::LINEAR);
svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6));
// Train the SVM with given parameters
Ptr<TrainData> td = TrainData::create(trainingDataMat, ROW_SAMPLE, labelsMat);
svm->train(td);
// Or train the SVM with optimal parameters
//svm->trainAuto(td);
Vec3b green(0, 255, 0), blue(255, 0, 0);
// Show the decision regions given by the SVM
for (int i = 0; i < image.rows; ++i)
for (int j = 0; j < image.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1, 2) << j, i);
float response = svm->predict(sampleMat);
if (response == 1)
image.at<Vec3b>(i, j) = green;
else if (response == -1)
image.at<Vec3b>(i, j) = blue;
}
// Show the training data
int thickness = -1;
int lineType = 8;
circle(image, Point(501, 10), 5, Scalar(0, 0, 0), thickness, lineType);
circle(image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType);
circle(image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
circle(image, Point(10, 501), 5, Scalar(255, 255, 255), thickness, lineType);
// Show support vectors
thickness = 2;
lineType = 8;
Mat sv = svm->getSupportVectors();
for (int i = 0; i < sv.rows; ++i)
{
const float* v = sv.ptr<float>(i);
circle(image, Point((int)v[0], (int)v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
}
imwrite("result.png", image); // save the image
imshow("SVM Simple Example", image); // show it to the user
waitKey(0);
}
The output should look like:
I found the code above worked but I needed to make a small modification to convert the labels to integers. The modification is in bold:
// Set up training data **Original**:
int labels[4] = { 1, -1, -1, -1 };
Mat labelsMat(4, 1, **CV_32SC1**, labels);
// Set up training data **Modified**:
int labels[4] = { 1, -1, -1, -1 };
Mat labelsMat(4, 1, **CV_32S**, labels);
I want to use convexity defects of a human hand as input to a classifier. I want to do this to detect hand gestures (sign language alphabet). Can someone please help me.
The code below is available on the opencv documentation. I want to know how to use this for my the purpose stated above.
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
// Set up training data
float labels[4] = { 1.0, -1.0, -1.0, -1.0 };
Mat labelsMat(4, 1, CV_32FC1, labels);
// Storing as Mat objects of floats
float trainingData[4][2] = { { 501, 10 }, { 255, 10 }, { 501, 255 }, { 10, 501 } };
Mat trainingDataMat(4, 2, CV_32FC1, trainingData);
// Set up SVM's parameters
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
// Train the SVM
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
Vec3b green(0, 255, 0), blue(255, 0, 0);
// Show the decision regions given by the SVM
for (int i = 0; i < image.rows; ++i)
for (int j = 0; j < image.cols; ++j)
{
Mat sampleMat = (Mat_<float>(1, 2) << j, i);
float response = SVM.predict(sampleMat);
if (response == 1)
image.at<Vec3b>(i, j) = green;
else if (response == -1)
image.at<Vec3b>(i, j) = blue;
}
// Show the training data
int thickness = -1;
int lineType = 8;
circle(image, Point(501, 10), 5, Scalar(0, 0, 0), thickness, lineType);
circle(image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType);
circle(image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType);
circle(image, Point(10, 501), 5, Scalar(255, 255, 255), thickness, lineType);
// Show support vectors
thickness = 2;
lineType = 8;
int c = SVM.get_support_vector_count();
for (int i = 0; i < c; ++i)
{
const float* v = SVM.get_support_vector(i);
circle(image, Point((int)v[0], (int)v[1]), 6, Scalar(128, 128, 128), thickness, lineType);
}
imwrite("result.png", image); // save the image
imshow("SVM Simple Example", image); // show it to the user
waitKey(0);
}
Please consider the MWE below. I have a matrix (output) that corresponds to a graphics output buffer and some layers, that should be put into that buffer in a specific order. The layers contain alpha information (last byte). If all layers have the alpha bytes of all pixels set to 0xFF, only the layer on top can be seen. If all have the alpha value set to 0, none can be seen. There can be an alpha value between 0 and 0xFF, so the corresponding pixel should be semi-transparent.
I tried to use addWeighted(), but this didn't help (see below): All images are visible no matter what value the alpha byte is set to.
Do you have any idea how this can be realized?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
void test(){
namedWindow("window", WINDOW_AUTOSIZE);
Mat output(Size(300, 300), CV_8UC4, Scalar(0));
Mat m1(Size(300, 300), CV_8UC4, Scalar(0));
Mat m2(Size(300, 300), CV_8UC4, Scalar(0));
Mat m3(Size(300, 300), CV_8UC4, Scalar(0));
circle(m1, Point(130, 130), 75, Scalar(0, 0, 0xFF, 0xFF), -1);
circle(m2, Point(150, 150), 75, Scalar(0, 0xFF, 0, 0xFF), -1);
rectangle(m3, Rect(100, 100, 60, 60), Scalar(0xFF, 0, 0, 0xFF), -1);
rectangle(m3, Rect(115, 115, 30, 30), Scalar(0), -1);
/*
Output should look like
[ m3 ] <-- top
[ m2 ]
[ m1 ] <-- bottom
*/
//What I've tried so far (the final solution should work for more than 3 'layers')
m1.copyTo(output);
addWeighted(output, .5, m2, .5, 0, output);
addWeighted(output, .5, m3, .5, 0, output);
imshow("window", output);
cvWaitKey(0);
destroyAllWindows();
}
I'm not sure if this is the best way to do it, but this will maybe do the job.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <stdio.h>
using namespace cv;
void addAlpha(Mat src, Mat input);
void test(){
namedWindow("window", WINDOW_AUTOSIZE);
Mat output(Size(300, 300), CV_8UC4, Scalar(0));
Mat m1(Size(300, 300), CV_8UC4, Scalar(0));
Mat m2(Size(300, 300), CV_8UC4, Scalar(0));
Mat m3(Size(300, 300), CV_8UC4, Scalar(0));
circle(m1, Point(130, 130), 75, Scalar(0, 0, 0xFF, 0xFF), -1);
circle(m2, Point(150, 150), 75, Scalar(0, 0xFF, 0, 0xFF), -1);
rectangle(m3, Rect(100, 100, 60, 60), Scalar(0xFF, 0, 0, 0xFF), -1);
rectangle(m3, Rect(115, 115, 30, 30), Scalar(0), -1);
m1.copyTo(output);
addAlpha(output,m2);
addAlpha(output,m3);
imshow("window", output);
cvWaitKey(0);
destroyAllWindows();
}
void addAlpha(Mat src, Mat input){
if(src.rows != input.rows || src.cols != input.cols){
perror("Not same size");
}
for(int i = 0; i < src.rows; i++){
for(int j = 0; j < src.cols; j++){
src.at<cv::Vec4b>(i,j)[0] = src.at<cv::Vec4b>(i,j)[0] * (1 - input.at<cv::Vec4b>(i,j)[3]/255.0) + input.at<cv::Vec4b>(i,j)[0] * (input.at<cv::Vec4b>(i,j)[3]/255.0);
src.at<cv::Vec4b>(i,j)[1] = src.at<cv::Vec4b>(i,j)[1] * (1 - input.at<cv::Vec4b>(i,j)[3]/255.0) + input.at<cv::Vec4b>(i,j)[1] * (input.at<cv::Vec4b>(i,j)[3]/255.0);
src.at<cv::Vec4b>(i,j)[2] = src.at<cv::Vec4b>(i,j)[2] * (1 - input.at<cv::Vec4b>(i,j)[3]/255.0) + input.at<cv::Vec4b>(i,j)[2] * (input.at<cv::Vec4b>(i,j)[3]/255.0);
}
}
}
I am trying to rotate four points(rectangle) around the middle point of them.
But the result looks strange.
I use the formula found here and on wikipedia
p.x'=p.x*cos(alpha) + p.y*sin(alpha);
p.y'=(-1)p.x*sin(alpha) + p.y*cos(alpha);
Is this formula applicable for my purpose (rotating rectangle)?
Here is the source, I try to rotate 33 degrees counter clockwise
Thank You, very much
Mat img(480, 800, CV_8UC4, Scalar(255,255,255,255));
Mat dst(480, 800, CV_8UC4, Scalar(255,255,255,255));
Point p1, p2, p3, p4;
Point center;
p1.x=501; p1.y=247;
p2.x=429; p2.y=291;
p3.x=388; p3.y=222;
p4.x=451; p4.y=186;
circle(img, p1, 3, Scalar(255, 0, 0, 255), 3, 8, 0 );
circle(img, p2, 3, Scalar(0, 255, 0, 255), 3, 8, 0 );
circle(img, p3, 3, Scalar(0, 0, 255, 255), 3, 8, 0 );
circle(img, p4, 3, Scalar(255, 255, 0, 255), 3, 8, 0 );
center.x = (p1.x+p2.x+p3.x+p4.x)/4;
center.y = (p1.y+p2.y+p3.y+p4.y)/4;
double alpha = -33 * 0.0174532925;
double s = sin(alpha);
double c = cos(alpha);
p1.x = (+c*(p1.x-center.x)* + s*(p1.y-center.y)) + center.x;
p1.y = (-s*(p1.x-center.x) + c*(p1.y-center.y)) + center.y;
p2.x = (+c*(p2.x-center.x)* + s*(p2.y-center.y)) + center.x;
p2.y = (-s*(p2.x-center.x) + c*(p2.y-center.y)) + center.y;
p3.x = (+c*(p3.x-center.x)* + s*(p3.y-center.y)) + center.x;
p3.y = (-s*(p3.x-center.x) + c*(p3.y-center.y)) + center.y;
p4.x = (+c*(p4.x-center.x)* + s*(p4.y-center.y)) + center.x;
p4.y = (-s*(p4.x-center.x) + c*(p4.y-center.y)) + center.y;
circle(dst, p1, 3, Scalar(255, 0, 0, 255), 3, 8, 0 );
circle(dst, p2, 3, Scalar(0, 255, 0, 255), 3, 8, 0 );
circle(dst, p3, 3, Scalar(0, 0, 255, 255), 3, 8, 0 );
circle(dst, p4, 3, Scalar(255, 255, 0, 255), 3, 8, 0 );
imshow("src", img);
imshow("dst", dst);
cvMoveWindow("dst", 0, img.cols+50);
waitKey(0);
return 0;
Your formula is correct. Your math looks fine. Your problem is probably just the extra * symbol:
p1.x = (+c*(p1.x-center.x)* + s*(p1.y-center.y)) + center.x;
^
This gets evaluated as:
p1.x = ((+c*(p1.x-center.x))* (+ s*(p1.y-center.y))) + center.x;
Just remove the *
So, i find the solution.
I noob overwrite previous x value with new computed values
This is the solution
for(int i = 0; i<360; i++)
{
Mat img(480, 800, CV_8UC4, Scalar(255,255,255,255));
Mat dst(480, 800, CV_8UC4, Scalar(255,255,255,255));
Point p1, p2, p3, p4;
Point center;
p1.x=501; p1.y=247;
p2.x=429; p2.y=291;
p3.x=388; p3.y=222;
p4.x=451; p4.y=186;
circle(img, p1, 3, Scalar(255, 0, 0, 255), 3, 8, 0 );
circle(img, p2, 3, Scalar(0, 255, 0, 255), 3, 8, 0 );
circle(img, p3, 3, Scalar(0, 0, 255, 255), 3, 8, 0 );
circle(img, p4, 3, Scalar(255, 255, 0, 255), 3, 8, 0 );
center.x = (p1.x+p2.x+p3.x+p4.x)/4;
center.y = (p1.y+p2.y+p3.y+p4.y)/4;
double alpha = -i * 0.0174532925;
double s = sin(alpha);
double c = cos(alpha);
int x = 0, y = 0;
x=p1.x; y=p1.y;
p1.x = (c*(x-center.x) - s*(y-center.y)) + center.x;
p1.y = (s*(x-center.x) + c*(y-center.y)) + center.y;
x=p2.x; y=p2.y;
p2.x = (c*(x-center.x) - s*(y-center.y)) + center.x;
p2.y = (s*(x-center.x) + c*(y-center.y)) + center.y;
x=p3.x; y=p3.y;
p3.x = (c*(x-center.x) - s*(y-center.y)) + center.x;
p3.y = (s*(x-center.x) + c*(y-center.y)) + center.y;
x=p4.x; y=p4.y;
p4.x = (c*(x-center.x) - s*(y-center.y)) + center.x;
p4.y = (s*(x-center.x) + c*(y-center.y)) + center.y;
circle(dst, p1, 3, Scalar(255, 0, 0, 255), 3, 8, 0 );
circle(dst, p2, 3, Scalar(0, 255, 0, 255), 3, 8, 0 );
circle(dst, p3, 3, Scalar(0, 0, 255, 255), 3, 8, 0 );
circle(dst, p4, 3, Scalar(255, 255, 0, 255), 3, 8, 0 );
imshow("src", img);
imshow("dst", dst);
cvMoveWindow("dst", 0, img.cols+50);
waitKey(20);