I'm trying to find connected components using contour functions but I'm getting an error for findContours function. I'm using opencv 2.4.7 and visual studio 2010
CvMat *mat = cvCreateMat(img->height,img->width,CV_32FC3 );
cvConvert( img, mat );
CvMat *thr = cvCreateMat(img->height,img->width,CV_32FC3);
cvCvtColor(mat,thr ,CV_RGBA2RGB);
cvThreshold(thr, thr,25, 255,CV_THRESH_BINARY); //Threshold the gray
int largest_area=0;
int largest_contour_index=0;
Rect bounding_rect;
vector<vector<Point>> contours; // Vector for storing contour
vector<Vec4i> hierarchy;
findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); //Find the contours in the image
errors:
IntelliSense: no suitable conversion function from "std::vector<std::vector<cv::Point, std::allocator<cv::Point>>, std::allocator<std::vector<cv::Point, std::allocator<cv::Point>>>>" to "CvMemStorage *" exists c:\users\shahd\documents\visual studio 2010\projects\test_opencv\test_opencv\main.cpp 41
IntelliSense: no suitable conversion function from "std::vector<cv::Vec4i, std::allocator<cv::Vec4i>>" to "CvSeq **" exists c:\users\shahd\documents\visual studio 2010\projects\test_opencv\test_opencv\main.cpp 41
The problem is that the datatype of your image is Mat which is used by C++ type of openCV. But the functions which you are using is of C type openCV.
So, instead of using cvThreshold(), try use threshold() as mentioned as this link.
Related
I need a way to overlay text on opencv image without actually modifying the underlying image. For example inside a while loop i create a random point for each iteration and I want to display it. If I use puttext the matrix gets overwritten with the added text in each cycle.
My questions is how to overlay text on opencv image without modifying the underlying matrix. I know I could use a temporary copy of the original image and upload it every time. However I want to avoid it.
My attempt(which fails) is as below:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main(int argc, char * argv[])
{
RNG rng( 0xFFFFFFFF );
cv::Mat image(480, 640, CV_8UC3, cv::Scalar(0,255,0));
int fontFace = FONT_HERSHEY_COMPLEX_SMALL;
double fontScale_small=1.5;
double fontScale_large=10.;
std::string text="X";
Point p;
while(1)
{
p.x = rng.uniform( 0, 639 );
p.y = rng.uniform( 0, 479 );
putText(image, "X", p, fontFace, 1, Scalar(0,0,255), 2);
imshow("IMAGE", image);
waitKey(1);
}
return 0;
}
If you are on OpenCV 3+ and have built OpenCV with Qt, then you can use the highgui functions on the Qt GUI window to overlay text, instead of actively modifying your image. See displayOverlay(). You can also simply change the status bar text, which is sometimes more useful (so that you don't cover the image or have to deal with color clashes) with displayStatusBar(). However, note that displayOverlay() does not allow you to give specific positions for your text.
Without QT support, I don't believe this is possible in OpenCV. You'll need to either modify your image via putText() or addText(), or roll your own GUI window that you can overlay text on.
You can output your text on black image, then make XOR with source image for put your text, and the second XOR will clear your text from source image.
I'm trying to declare a vector for storing contour but I'm getting an error for the following:
code:
Rect bounding_rect;
vector<vector<Point>> contours; // Vector for storing contour
vector<Vec4i> hierarchy;
errors:
'Rect' undeclared identifier,
'Point' undeclared identifier,
'vector' unspecialized class template cant be used as a template argument,
'Vec4i' undefined,
Please could someone help me?
either try :
cv::Rect
cv::Vec4i
cv::Point
or add:
using namespace cv;
after the headers
I want to write to an image a formatted text. OpenCV offers only a limited set of default fonts. Is it possible to use others? For example to read them from the *.ttf file (in Ubuntu)?
If you cannot or don't want to use the Qt bindings, here is a way to do it with CAIRO:
#include <opencv2/opencv.hpp>
#include <cairo/cairo.h>
#include <string>
void putTextCairo(
cv::Mat &targetImage,
std::string const& text,
cv::Point2d centerPoint,
std::string const& fontFace,
double fontSize,
cv::Scalar textColor,
bool fontItalic,
bool fontBold)
{
// Create Cairo
cairo_surface_t* surface =
cairo_image_surface_create(
CAIRO_FORMAT_ARGB32,
targetImage.cols,
targetImage.rows);
cairo_t* cairo = cairo_create(surface);
// Wrap Cairo with a Mat
cv::Mat cairoTarget(
cairo_image_surface_get_height(surface),
cairo_image_surface_get_width(surface),
CV_8UC4,
cairo_image_surface_get_data(surface),
cairo_image_surface_get_stride(surface));
// Put image onto Cairo
cv::cvtColor(targetImage, cairoTarget, cv::COLOR_BGR2BGRA);
// Set font and write text
cairo_select_font_face(
cairo,
fontFace.c_str(),
fontItalic ? CAIRO_FONT_SLANT_ITALIC : CAIRO_FONT_SLANT_NORMAL,
fontBold ? CAIRO_FONT_WEIGHT_BOLD : CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_font_size(cairo, fontSize);
cairo_set_source_rgb(cairo, textColor[2], textColor[1], textColor[0]);
cairo_text_extents_t extents;
cairo_text_extents(cairo, text.c_str(), &extents);
cairo_move_to(
cairo,
centerPoint.x - extents.width/2 - extents.x_bearing,
centerPoint.y - extents.height/2- extents.y_bearing);
cairo_show_text(cairo, text.c_str());
// Copy the data to the output image
cv::cvtColor(cairoTarget, targetImage, cv::COLOR_BGRA2BGR);
cairo_destroy(cairo);
cairo_surface_destroy(surface);
}
Example call:
putTextCairo(mat, "Hello World", cv::Point2d(50,50), "arial", 15, cv::Scalar(0,0,255), false, false);
It assumes that the target image is BGR.
It puts the text's center to the given point. If you want some different positioning, you have to modify the cairo_move_to call.
It's possible to use other fonts but you need to link the Qt library to OpenCV and use the cvAddText function with a cvFontQt
http://docs.opencv.org/modules/highgui/doc/qt_new_functions.html#addtext
http://docs.opencv.org/modules/highgui/doc/qt_new_functions.html#fontqt
There are other solutions you might try, with more or less the same performance as OpenCV. For instance, you can use CAIRO to write fonts into the image.
I have a binary file of 16 bit Intensity of the image. I have read this data in short array. And create 16 bit gray Image using the following code.
IplImage *img=cvCreateImage( cvSize( Image_width, Image_height ), IPL_DEPTH_16S, 1 );
cvSetData(img,Data, sizeof(short )*Image_width);
Where Data is short array.
Then I set ROI for this Image using this function
cvSetImageROI(img, cvRect(crop_start.x, crop_start.y, crop_width, Image_height));
and ROI is being set successfully.
Now after setting the ROI I want to access the Intensity of the Image means I want pointer of the intensity of the cropped Image. I have tried this code to access the intensity
short *crop_Imagedata=(short *)img->imageData;
But This pointer is not giving the right Intensity as I have checked that by debugging the code.
Can any body please tell me how can I get pointer of the Image Intensity.
Thanks in Advance
Hello I have tryed the following to find what maybe you wannt to do:
IplImage *img=cvCreateImage( cvSize( 15, 15 ), IPL_DEPTH_16S, 1 );
cvSet(img,cvScalar(15));//sets all values to 15
cvSetImageROI(img, cvRect(4, 0, 10, 15));
short *crop_Imagedata=(short *)img->imageData;
((*crop_Imagedata) == 15) // true
The value that you will get is not in the roi! imageData of the IplImage structure is just a simple pointer and not a function !!! the rois of opencv is something that isn t that well documented and easy to use in my opinion. Maybe all algorithms of opencv use the rois somehow. I use them to but there is no such automatic function with the standard iplimage structure to simple use them.
If you wannt more magic try to use the new cv::Mat object...
but if you still wann t to use rois then you will have to allways to use
CvRect roi = cvGetImageROI(img);
method to check all the time the position. After that you will have to add the roi offset:
((short*)(img->imageData + (roi.y+ypos)*img-widthStep))[roi.x+xpos]
remember the standard Opencv is a C library not a C++ ! btw when mixing cv::Mat rois can be a bit annoying to. To copy an iplimage to a cv::Mat without roi I have to do the following:
CvRect roitmp = cvGetImageROI(ilimage);
cvResetImageROI(ilimage);
cv::Mat tmp = cv::Mat(ilimage).clone();
cvSetImageROI(ilimage,roitmp);
maybe here someone knows the right way of working with rois...
Quancomm Augmented Reality (QCAR) for iOS, which make use of OpenGL ES, to display 3D model. It reads several files:
vertices, texture coordinates, indices & normals list (in format of ONE .h header file, e.g. Teapot.h)
texture file (in PNG format)
shader file (in FSH and VSH format)
My question is, how to convert a 3D Studio Max (3ds/max) file to the vertices, texture coordinates, indices & normals list? Also, during the conversion process, can the shader file be generated based on the settings in 3DS file as well?
The files are used in QCAR SDK for iOS, version 1.0.
As an example, the file content is as follow:
#ifndef _QCAR_TEAPOT_OBJECT_H_
#define _QCAR_TEAPOT_OBJECT_H_
#define NUM_TEAPOT_OBJECT_VERTEX 824
#define NUM_TEAPOT_OBJECT_INDEX 1024 * 3
static const float teapotVertices[NUM_TEAPOT_OBJECT_VERTEX * 3] =
{
// vertices here
};
static const float teapotTexCoords[NUM_TEAPOT_OBJECT_VERTEX * 2] =
{
// texture coordinates here
};
static const float teapotNormals[NUM_TEAPOT_OBJECT_VERTEX * 3] =
{
// normals here
};
static const unsigned short teapotIndices[NUM_TEAPOT_OBJECT_INDEX] =
{
// indices here
};
#endif
i believe that what you are looking for, is here: 3DS to Header utility.
In answer to your second question, 3DS material settings could be in theory converted to shaders if someone wrote all possible shaders that 3DS can use and programmed some code to select and configure the shader, based on material properties. But no, there is no direct / easy way how to do that. Although, if i recall correctly, 3DS doesn't have too many material choices so there might be not too many shaders required in order to do this.