I am trying to make Open CV project sample for Template Matching as explained here .
Steps i did so far includes :
Downloaded and imported Open CV framework in my project changed the .m extension files to .mm and in the .pch file i have included the code
#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif
I have also downloaded and imported the MatchTemplate_Demo.cpp file from the link.
But here having library linking issue
ld: warning: directory not found for option '-L/Users/G1/Desktop/Xcode'
ld: warning: directory not found for option '-Lprojects/FirstOpenCv/opencv/lib/debug'
ld: library not found for -lopencv_calib3d
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I followed the same step to include the library as given here.
2) Add $(SRCROOT)/opencv to header search path and $(SRCROOT)/opencv/lib/debug for library search path for debug configuration and $(SRCROOT)/opencv/lib/release for release build.
3) Add OpenCV libs to linker input by modifying "Other Linker Flags" option with "-lopencv_calib3d -lzlib -lopencv_contrib -lopencv_legacy -lopencv_features2d -lopencv_imgproc -lopencv_video -lopencv_core".
Now can please any one tell me how should i make the project run.
I have taken the source and template image and imported in the project.
I have basically ViewController.h and ViewController.mm file now i don't know what should i code in these files to see the result.
Also Step 2 :
I need to scan the image in real time using camera view (so that when i place my camera over the source image it should scan and find the template).
On following this link i got Linker error while importing the .cpp file :
ld: 1 duplicate symbol for architecture i386 clang:
error: linker command failed with exit code 1 (use -v to see invocation)
Please can any one suggest me how should i implement it.
You have three interrelated questions here:
1/ how to get openCV framework to run in an iOS project
2/ how to get the Template Matching c++ sample code to run in an iOS project
3/ how to do live template matching with the camera view
1/ how to get openCV framework to run in an iOS project
Download and import the openCV framework as you describe
Change the .pch file as you describe
check that c++ standard library is set to libc++ in your target build settings (this is the default for new projects)
Don't just import demo.cpp without making changes as described below (it is a 'raw' c++ progam with it's own main function, and needs alterations to work as part of an iOS/Cocoa project).
Don't mess with header search paths, other linker flags etc, this isn't necessary if you have imported the prebuilt framework from openCV.org.
Don't change your .m files to .mm unless you know that you need to. My advice is to keep your c++ code separate from your objective-C code as far as practicable, so most of you files should be .m files (objective-C) or .cpp files (c++). You only need .mm prefixes for "objective-C++" where you intend to mix objective-C and c++ in the same file.
2/ how to get the Template Matching c++ sample code to run in an iOS project
We are going to set this up so that your iOS viewController - and the bulk of your iOS code - does not need to know that the image is processed using openCV/C++, and likewise the C++ code doesn't need to know where it's input or output image data is being routed to. We do this by making a small wrapper class between the two that translates objective-C method calls to c++ class member functions and back. We will also set up a category on UIImage to translate image formats from iOS-friendly UIImage to openCV-native cv::Mat.
UIImage+OpenCV Category
You need some utility methods to convert from UIImage to cv::Mat and back. A good place to put these is in a UIImage category. In XCode: File>New FIle>Cocoa Touch>Objective-C category will set you up. Call the category OpenCV and make it a category on UIImage. This .m file you will want to change to .mm as it will need to understand c++ types from the openCV framework.
The header should look something like this:
#import <UIKit/UIKit.h>
#interface UIImage (OpenCV)
//cv::Mat to UIImage
+ (UIImage *)imageWithCVMat:(const cv::Mat&)cvMat;
//UIImage to cv::Mat
- (cv::Mat)cvMat;
#end
The .mm file should implement these methods by closely following this openCV.org code sample adapted to work as category methods (eg you don't pass a UIImage into the instance method, but refer to it using self).
You can use the category methods as if they are UIImage class and instance methods like this:
UIImage* image = [UIImage imageWithCVMat:matImage]; //class method
cv::Mat matImage = [image cvMat]; //instance method
openCV wrapper class
Make a wrapper class to convert your objective-C method (called from a viewController) to a c++ function
header something like this
// CVWrapper.h
#import <Foundation/Foundation.h>
#interface CVWrapper : NSObject
+ (NSImage*) templateMatchImage:(UIImage*)image
patch:(UIImage*)patch
method:(int)method;
#end
We send in the template image, patch image and template matching method, and get back an image showing the match
implementation (.mm file)
// CVWrapper.mm
#import "CVWrapper.h"
#import "CVTemplateMatch.h"
#import "UIImage+OpenCV.h"
#implementation CVWrapper
+ (UIImage*) templateMatchImage:(UIImage *)image
patch:(UIImage *)patch
method:(int)method
{
cv::Mat imageMat = [image cvMat];
cv::Mat patchMat = [patch cvMat];
cv::Mat matchImage =
CVTemplateMatch::matchImage(imageMat,
patchMat,
method);
UIImage* result = [UIImage imageWithCVMat:matchImage];
return result;
}
We are effectively taking a standard objective-C method and UIImage types and translating them into a call to a C++ member function with c++(openCV framework) types, and translating the result back to a UIImage.
C++ TemplateMatch class
Header:
// TemplateMatch.h
#ifndef __CVOpenTemplate__CVTemplateMatch__
#define __CVOpenTemplate__CVTemplateMatch__
class CVTemplateMatch
{
public:
static cv::Mat matchImage (cv::Mat imageMat,
cv::Mat patchMat,
int method);
};
#endif /* defined(__CVOpenTemplate__CVTemplateMatch__) */
#end
Implementation:
This is the Template Match openCV example code, reworked as a class implementation:
// TemplateMatch.cpp
/*
Alterations for use in iOS project
[1] remove GUI code (iOS supplies the GUI)
[2] change main{} to static member function
with appropriate inputs and return value
[3] change MatchingMethod{} signature
to return Mat value
*/
#include "CVTemplateMatch.h"
//[1] #include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/// Global Variables
Mat img; Mat templ; Mat result;
//[1] char* image_window = "Source Image";
//[1] char* result_window = "Result window";
int match_method;
//[1] int max_Trackbar = 5;
/// Function Headers
Mat MatchingMethod( int, void* ); //[3] (added return value to function)
// [2] /** #function main */
// [2] int main( int argc, char** argv )
Mat CVTemplateMatch::matchImage (Mat image,Mat patch, int method)
// [2]
{
/// Load image and template
//[2] img = imread( argv[1], 1 );
//[2] templ = imread( argv[2], 1 );
img = image; //[2]
templ = patch; //[2]
match_method = method; //[2]
/// Create windows
//[1] namedWindow( image_window, CV_WINDOW_AUTOSIZE );
//[1] namedWindow( result_window, CV_WINDOW_AUTOSIZE );
/// Create Trackbar
//[1] char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
//[1] createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );
Mat result = MatchingMethod( 0, 0 );
//[1] waitKey(0);
//[2] return 0;
return result; //[2]
}
//[3] void MatchingMethod( int, void* )
Mat MatchingMethod( int, void* )
{
/// Source image to display
Mat img_display;
img.copyTo( img_display );
/// Create the result matrix
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );
/// Localizing the best match with minMaxLoc
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{ matchLoc = minLoc; }
else
{ matchLoc = maxLoc; }
/// Show me what you got
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
//[1] imshow( image_window, img_display );
//[1] imshow( result_window, result );
return img_display; //[3] add return value
}
Now in your viewController you just need to call this method:
UIImage* matchedImage =
[CVWrapper templateMatchImage:self.imageView.image
patch:self.patchView.image
method:0];
with no c++ in sight.
3/ Template Matching with live camera view
The short answer: matchTemplate is not going to work too well in a live camera context. The algorithm is looking for a match in the image with the same scale and orientation as the patch: it slides the patch tile across the image at it's original orientation and size comparing for best match. This is not going to yield great results if the image is perspective-skewed, a different size or rotated to a different orientation.
You could look instead at OpenCV's Feature Detection algorithms, some of which have been moved to non-free. Here is a nice description of SIFT to give you the idea. For video capture you might also want to look at cap_ios.h in opencv2/highgui: here is a tutorial.
Actually you have downloaded already compiled library so no need to follow the steps that you have mentioned in your question and this the issues(i.e. you have followed incorrect steps) because that steps are to compile the source code into static library.
Follow the below steps and it will be done
Unzip the downloaded framework. You can see folder with name "opencv2.framework"
Drag that folder directly into project(Note. When you drag that folder into xcode, xcode will prompt you dialog there will be a tick mark to actually copy this into folder. please tick that check box)
In you .pch file import openCV like you have mentioned in your question is correct way
Now compile. One thing more wherever you want to use function of openCV that file should have .mm extension(i.e. Objective C++ source) It will run perfectly.
Help link:
Related
I've a problem with cairo_debug_reset_static_data() function when I combine both pango lib and cairo as I am getting the following assertion when its get called.
draw: cairo-hash.c:217: _cairo_hash_table_destroy: Assertion `hash_table->live_entries == 0' failed.
Here's the code I took from the following post: where some one had similar problem but they have not shared any working solution there(I already tried solution from the post, but it did not work). If we remove the commented lines then there is assertion.
#include <cairo.h>
#include <pango/pangocairo.h>
int
main (int argc, char *argv[])
{
cairo_surface_t *surface;
cairo_t *context;
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 120, 120);
context = cairo_create(surface);
PangoRectangle extents;
PangoLayout *layout;
PangoFontDescription *desc;
layout = pango_cairo_create_layout (context);
desc = pango_font_description_from_string("Inconsolata 12");
pango_layout_set_font_description(layout, desc);
pango_font_description_free(desc);
pango_layout_set_markup(layout, "hello", -1);
//pango_layout_get_pixel_extents(layout, &extents, NULL);
//pango_cairo_show_layout(context, layout);
g_object_unref(layout);
cairo_destroy(context);
cairo_surface_destroy(surface);
cairo_debug_reset_static_data();
return(0);
}
I have tried to play around it to fix this problem, and also searched their documentation but could not find anything useful. Some one with expertise on pangocairo, please shed some light and point me to right direction.
Thanks
Here's the code I took from the following post: where some one had similar problem but they have not shared any working solution there.
Well, did you see the reply to that post? It contains everything you need to know to fix this assertion failure:
Add a call to pango_cairo_font_map_set_default(NULL); before calling
cairo_debug_reset_static_data();. That makes PangoCairo unreference the fonts
that it still has alive.
I am new to C/C++ environment setup. Right now I am using Eclipse IDE. Below are the steps I have followed
After installing MinGW and running basic HelloWorld, C program
1) Copied glew32.dll and glut32.dll to "C:\MinGW\bin"
2) Copied gl.h, glew.h, glu.h and glut.h to "C:\MinGW\include\GL"
3) Copied glew32.lib, glut32.lib and OPENGL32.LIB to "C:\MinGW\lib"
4) In Project->properties->C/C++ Build->Settings->Tool Settings->MinGW C Linker->Libraries(-l) added "glew32", "glut32","glu32" and "opengl32"
5) Copied below code
Compiles properly.
The moment I uncomment the first line, ie glew.h, glut related compile errors (added below) appear, Can any one tell me where I am going wrong during setup?
//#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glut.h>
void changeViewport(int w, int h)
{
glViewport(0, 0, w, h);
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("Pinnen is the best");
glutReshapeFunc(changeViewport);
glutDisplayFunc(render);
glutMainLoop();
return 0;
}
Description Resource Path Location Type
undefined reference to `__glutCreateMenuWithExit' OpenGL line 549, external location: c:\mingw\include\GL\glut.h C/C++ Problem
undefined reference to `__glutCreateWindowWithExit' OpenGL line 503, external location: c:\mingw\include\GL\glut.h C/C++ Problem
undefined reference to `__glutInitWithExit' OpenGL line 486, external location: c:\mingw\include\GL\glut.h C/C++ Problem
undefined reference to `glutDisplayFunc' OpenGL.c /OpenGL/src line 25 C/C++ Problem
undefined reference to `glutInitDisplayMode' OpenGL.c /OpenGL/src line 21 C/C++ Problem
//ignore
From glew webpage [delete gl include] :
Using GLEW as a shared library
in your program:
#include <GL/glew.h>
#include <GL/glut.h>
<gl, glu, and glut functionality is available here>
or:
#include <GL/glew.h>
<gl and glu functionality is available here>
Remember to link your project with glew32.lib, glu32.lib, and opengl32.lib on Windows and libGLEW.so, libGLU.so, and libGL.so on Unix (-lGLEW -lGLU -lGL).
It is important to keep in mind that glew.h includes neither windows.h nor gl.h. Also, GLEW will warn you by issuing a preprocessor error in case you have included gl.h, glext.h, or glATI.h before glew.h.
I've been trying to set a background image on a gtk widget without success, even after trying 4 different approaches.
The following program contains 3 approaches (the 4th approach involves no code). I compiled it using MinGW (g++ 4.5.0) and gtkmm 2.4. The APPROACH macro can be set to 1, 2 or 3 in order to choose which approach to compile. I've also added references in the comments, so you can find out where I got the ideas from.
#include <iostream>
#include <gtkmm/main.h>
#include <gtkmm/alignment.h>
#include <gtkmm/box.h>
#include <gtkmm/entry.h>
#include <gtkmm/eventbox.h>
#include <gtkmm/frame.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>
#include <gtkmm/table.h>
#include <gtkmm/window.h>
// Set this to 1, 2 or 3 to try different ways of drawing the background
// Set to 0 to load no background at all
#define APPROACH (0)
// Making this alignment global in order to modify it from drawBackground
Gtk::Alignment* alignment;
bool drawBackground(GdkEventExpose* event) {
std::cout << "Draw background" << std::endl;
// Load background image
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_file("background.jpg");
Glib::RefPtr<Gdk::Pixmap> pixmap;
Glib::RefPtr<Gdk::Bitmap> mask;
pixbuf->render_pixmap_and_mask(pixmap, mask,0);
{
// Test that pixbuf was created correctly
Glib::RefPtr<Gdk::Pixbuf> back_to_pixbuf = Gdk::Pixbuf::create((Glib::RefPtr<Gdk::Drawable>)pixmap, 0, 0, pixbuf->get_width(), pixbuf->get_height());
back_to_pixbuf->save("back_to_pixbuf.png", "png");
}
#if APPROACH == 1
// Approach 1: draw_pixbuf
// Ref: http://islascruz.org/html/index.php/blog/show/Image-as-background-in-a-Gtk-Application..html
Glib::RefPtr<Gtk::Style> style = alignment->get_style();
alignment->get_window()->draw_pixbuf(style->get_bg_gc(Gtk::STATE_NORMAL), pixbuf, 0, 0, 0, 200, pixbuf->get_width(), pixbuf->get_height(), Gdk::RGB_DITHER_NONE, 0, 0);
#endif
#if APPROACH == 2
// Approach 2: set_back_pixmap
// Ref: http://www.gtkforums.com/viewtopic.php?t=446
// http://stackoverflow.com/questions/3150706/gtk-drawing-set-background-image
alignment->get_window()->set_back_pixmap(pixmap);
#endif
}
int main (int argc, char *argv[])
{
Gtk::Main kit(argc, argv);
Gtk::Window w;
Gtk::VBox mainBox;
// Top image
Gtk::Image topImage("header.jpg");
mainBox.pack_start(topImage,false,false,0);
// Middle alignment
alignment = Gtk::manage(new Gtk::Alignment);
mainBox.pack_start(*alignment,true,true,0);
// Create widget
Gtk::Alignment mywidget(0.5, 0.5, 0.1, 0.9);
Gtk::Table table;
Gtk::Label label1("Username"); table.attach(label1,0,1,0,1);
Gtk::Label label2("Password"); table.attach(label2,0,1,1,2);
Gtk::Entry entry1; table.attach(entry1,1,2,0,1);
Gtk::Entry entry2; table.attach(entry2,1,2,1,2);
Gtk::Button button("Login"); table.attach(button,1,2,2,3);
mywidget.add(table);
// Put widget in middle alignment
alignment->add(mywidget);
// Try to change the background
#if APPROACH == 1 || APPROACH == 2
alignment->signal_expose_event().connect(sigc::ptr_fun(&drawBackground), true);
#endif
#if APPROACH == 3
// Approach 3: modify the style using code
// Ref: http://www.gtkforums.com/viewtopic.php?t=446
// Load background image
Glib::RefPtr<Gdk::Pixbuf> pixbuf = Gdk::Pixbuf::create_from_file("background.jpg");
Glib::RefPtr<Gdk::Pixmap> pixmap;
Glib::RefPtr<Gdk::Bitmap> mask;
pixbuf->render_pixmap_and_mask(pixmap, mask,0);
Glib::RefPtr<Gtk::Style> style = alignment->get_style()->copy();
style->set_bg_pixmap(Gtk::STATE_NORMAL,pixmap);
style->set_bg_pixmap(Gtk::STATE_ACTIVE,pixmap);
style->set_bg_pixmap(Gtk::STATE_PRELIGHT,pixmap);
style->set_bg_pixmap(Gtk::STATE_SELECTED,pixmap);
style->set_bg_pixmap(Gtk::STATE_INSENSITIVE,pixmap);
alignment->set_style(style);
#endif
// Approach 4: modify share\themes\MS-Windows\gtk-2.0
// adding the following line
// bg_pixmap[NORMAL] = "D:\\path\\to\\file\\background.jpg"
// in the style "msw-default" section
// Ref: http://lists.ximian.com/pipermail/gtk-sharp-list/2005-August/006324.html
// Show the window
w.add(mainBox);
w.show_all();
kit.run(w);
return 0;
}
Links to images I used: header.jpg background.jpg
The layout mimics that of my actual program. The main window contains a Gtk::VBox with a header image on top and an Gtk::Alignment at the bottom. The contents of this alignment will change over time but I want it to have a background image always visible.
When loading no background at all, the header image loads correctly and the window looks like this:
Approach 1 is the one that is closer to work, though it hides the labels and the buttons:
Approaches 2 and 3 look the same as loading no background. Besides, approach 2 gives me the following error message:
(test-img-fondo.exe:1752): Gdk-CRITICAL **: gdk_window_set_back_pixmap: assertion `pixmap == NULL || !parent_relative' failed
Finally, in approach 4, I attempt to modify share\themes\MS-Windows\gtk-2.0 by adding the following line
bg_pixmap[NORMAL] = "D:\\path\\to\\file\\background.jpg"
in the style "msw-default" section. It doesn't work either.
So, has anyone succesfully drawn a background image on a Gtk widget? Is this possible at all? Any changes in my code that would make this work? Any workarounds?
All help is greatly appreciated.
I think I've solved it myself. Use approach 1 but change this line
alignment->signal_expose_event().connect(sigc::ptr_fun(&drawBackground), true);
for this:
alignment->signal_expose_event().connect(sigc::ptr_fun(&drawBackground), false);
This way, the call to drawBackground occurs before gtk calls its own handlers.
I should also point out that, in a real program, the images should be loaded once outside of drawBackground.
Just wondering how difficult it would be to convert the following library to Objective-C to be used on the iPhone?
I guess I'm after some similar image processing libraries that would lead me in the right direction? I'm aware that it's not easy to apply the same filters as existing applications like Instragram, Path and Hipstamatic.
However, I'd like to be able to do something similar.
Here is the JavaScript library:
https://github.com/alexmic/filtrr/blob/master/filtrr.js
A demo of its functionality can be found here:
http://alexmic.net/demos/filtrr
I've started a bit of converting, here is a sample. Now of course, fully converting it would a lot of time, too much for me to do it. But just see how I've done it. I'm hoping you have prior experience with Obj-C?
Also, perhaps you could look at some existing libraries.
http://code.google.com/p/simple-iphone-image-processing/
http://mattgemmell.com/2010/07/05/mgimageutilities/
http://developer.apple.com/library/ios/#samplecode/GLImageProcessing/Introduction/Intro.html
Also, dont forget that XCode can compile C++ into your project so also investigate C or C++ libraries.
NSObject canvas;
int w;
int h;
int ctx;
NSData imageData;
#implementation filtr
{
-(id) initWithCanvas:(id)_canvas
{
if (!_canvas) {
throw "Canvas supplied to filtr was null or undefined.";
}
canvas = _canvas;
w = canvas.width;
h = canvas.height;
ctx = canvas.getContext("2d");
imageData = ctx.getImageData(0, 0, w, h);
}
/**
* Clamps the intensity level between 0 - 255.
*
* #param i The intensity level.
*/
-(int)safe:(int)i
{
return MIN(255, MAX(0, i));
}
I'm in the process of learning opengles / obj-c and creating an app for the iphone that will render multiple 3d models. I've created an object that stores all the important details such as vertices / faces / textures etc but I also want to store the texture name that is currently being used on the model. In my CustomModels.h file I have:
#interface CustomModels : NSObject {
Vertex3D *vertices;
int numberOfFaces;
Face3D *faces;
Tex3D *texCoords;
BOOL active;
NSMutableArray *textures;
GLuint activeTexture;
}
then in my view controller .m file I'm trying to store the texture name like this:
glGenTextures(1, oModel.activeTexture);
But receive this error:
lvalue required as unary '&' operand
I'm a complete starter in obj-c programming so if anyone can point me in the right direction it would be much appreciated! Many thanks!
glGenTextures expects a pointer to a GLuint as its second parameter. You cannot use an Objective-C property (which is just another way of writing [oModel activeTexture]) in this place. Use a temp local variable instead:
GLuint texture = 0;
glGenTextures(1, &texture);
oModel.activeTexture = texture;