Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Objective-C Discussion :

Utilisation de C++ dans du code d'ObjC


Sujet :

Objective-C

  1. #1
    Nouveau membre du Club
    Utilisation de C++ dans du code d'ObjC
    Bonjour à tous.

    Je suis en train de faire un petit projet sur iPhone, et j'ai besoin d'utiliser le framework openCV pour faire des manipulations d'images.

    Le soucis, c'est que le code lié au framework openCV doit être écrit en C++.

    Etant un grand débutant dans le domaine du dev iPhone, j'ai trouvé qu'il fallait mettre ces lignes autour du code écrit en C++ pour qu'il soit compris.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    #ifdef __cplusplus
    #endif


    Mais apparemment, et de manière logique si on crée un object en ObjC, on ne peut pas s'en servir dans le code en C++ situé juste après :

    Exemple:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    NSString* filename = [[NSBundle mainBundle] pathForResource:@"openCV" ofType:@"jpg"];
        UIImage *image = [UIImage imageWithContentsOfFile:filename];
    
        if(image != nil) {
            #ifdef __cplusplus
            cv::Mat m, gray;
            UIImageToMat(image, m);
            cv::cvtColor(m, gray, CV_RGBA2GRAY);
            cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.2, 1.2);
            cv::Canny(gray, gray, 0, 50);
            m = cv::Scalar::all(255);
            m.setTo(cv::Scalar(0, 128, 255, 255), gray);
            imageView.contentMode = UIViewContentModeScaleAspectFit;
            imageView.image = MatToUIImage(m);
            #endif
        }


    Ca ne fonctionne pas, je n'ai pas d'erreur dans le code (pas de texte souligné, pas d'erreur de compilation) mais ça ne donne pas l'effet voulu, sachant qu'il s'agit d'un copier coller d'un tuto (en pdf, donc difficilement joignable),

    En fait, le tuto demande de copier/coller le if tel que je l'ai mis ici, sans les #ifdef et #endif. Mais sans ces lignes, le code en C++ c'est simplement pas reconnu.

    Je pige pas trop ce qu'il se passe en fait, quelqu'un peut m'éclairer ?

  2. #2
    Modérateur

    Bonsoir,

    Tu pourras peut être trouver quelques infos ici : http://philjordan.eu/article/strateg...ive-c-projects

    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  3. #3
    Nouveau membre du Club
    Merci pour le lien, mais j'avoue être un peu perdu...

    Ben déjà j'ai eu pas mal de mal à tout comprendre, et j'ai d'ailleurs apparemment pas tout compris sur ce lien.

    J'ai regardé sur cette page ci d'autres renseignements : http://bertrandleclercq.blogspot.fr/...du-code-c.html

    Mais lorsque j'essaie ça avec mon projet, je me rend compte que lon cas plus compliqué que celui présenté, où il y a bien 2 parties distinctes de C++ et d'ObjC.

    Dans mon cas, j'ai des méthodes en C++ qui utilisent des objets d'ObjC, et je voudrais attribué à un objet d'ObjC le retour d'une méthode en C++. Et donc ca en fonctionne pas.

    Voici globalement mon code, si quelqu'un peut me dire ce qui va pas la dedans, svp :/
    je précise que le contenu des méthodes est un copier/coller d'un tuto que j'ai suivi, mais qui n'évoque pas une seul fois cette histoire de C++... alors qu'il se sert de C++...


    Mon fichier ViewController.h
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    #import <UIKit/UIKit.h>
     
    @interface ViewController : UIViewController
    @property (weak, nonatomic) IBOutlet UIImageView *imageView;
     
    @end

    _____________________________________________________________________

    Mon fichier ViewController.mm

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
     
    #import "ViewController.h"
     
    @interface ViewController ()
     
    @end
     
    @implementation ViewController
    @synthesize imageView;
     
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	// Do any additional setup after loading the view, typically from a nib.
        NSString* filename = [[NSBundle mainBundle] pathForResource:@"openCV" ofType:@"jpg"];
        UIImage *image = [UIImage imageWithContentsOfFile:filename];
     
        if(image != nil) {
     
            cv::Mat m, gray;
            UIImageToMat(image, m);
            cv::cvtColor(m, gray, CV_RGBA2GRAY);
            cv::GaussianBlur(gray, gray, cv::Size(5, 5), 1.2, 1.2);
            cv::Canny(gray, gray, 0, 50);
            m = cv::Scalar::all(255);
            m.setTo(cv::Scalar(0, 128, 255, 255), gray);
            imageView.contentMode = UIViewContentModeScaleAspectFit;
            imageView.image = MatToUIImage(m);
     
        }
    }
     
    - (void)viewDidUnload
    {
        [self setImageView:nil];
        [super viewDidUnload];
        // Release any retained subviews of the main view.
    }
     
     
    static UIImage* MatToUIImage(const cv::Mat& m) {
        CV_Assert(m.depth() == CV_8U);
        NSData *data = [NSData dataWithBytes:m.data length:m.elemSize()*m.total()];
        CGColorSpaceRef colorSpace = m.channels() == 1 ?
        CGColorSpaceCreateDeviceGray() : CGColorSpaceCreateDeviceRGB();
        CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
        // Creating CGImage from cv::Mat
        CGImageRef imageRef = CGImageCreate(m.cols, m.cols, m.elemSize1()*8, m.elemSize()*8,
                                            m.step[0], colorSpace, kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault,
                                            provider, NULL, false, kCGRenderingIntentDefault);
        UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
        CGImageRelease(imageRef); CGDataProviderRelease(provider);
        CGColorSpaceRelease(colorSpace); return finalImage;
    }
     
    static void UIImageToMat(const UIImage* image, cv::Mat& m) {
        CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
        CGFloat cols = image.size.width, rows = image.size.height;
        m.create(rows, cols, CV_8UC4); // 8 bits per component, 4 channels
        CGContextRef contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8, m.step[0], colorSpace, kCGImageAlphaNoneSkipLast |kCGBitmapByteOrderDefault);
        CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);
        CGContextRelease(contextRef); CGColorSpaceRelease(colorSpace);
    }
     
    - (BOOL)shouldAutorotateToInterfaceOrientation<img src="images/smilies/icon_sad.gif" border="0" alt="" title=":(" class="inlineimg" />UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    }
     
    - (IBAction)effectButtonPressed<img src="images/smilies/icon_sad.gif" border="0" alt="" title=":(" class="inlineimg" />id)sender {
    }
    @end


    Sachant que je n'ai pas d'erreur de syntaxe ni rien, pas la moindre ligne de code soulignée, mais lors de la compilation, j'ai 20 erreurs de ce types :

    Apple Mach -O Linker (Id) Error
    et ce genre de chose dans le log :

    Undefined symbols for architecture i386:
    "cv::Exception::Exception(int, std::string const&, std::string const&, std::string const&, int)", referenced from:
    __ZL12MatToUIImageRKN2cv3MatE in ViewController.o

  4. #4
    Nouveau membre du Club
    Vu que je n'arrive pas à m'en sortir, je suis en train de suivre un autre tutoriel dans lequel les méthodes de conversions d'image en map sont des méthodes en Objective C.
    http://docs.opencv.org/trunk/doc/tut...ipulation.html
    Voici le tuto en question, vu l'URL du site, il me semble que c'est quand même pas mal viable.

    Mon nouveau soucis, le voila :

    J'ai mes méthodes en ObjC, mais au moment de les appeler pour faire mes transformations, il me dit :
    "Use of undeclared identifier 'maméthodeenquestion'".

    je tombe toujours sur un os ^^.

    Donc ce coup ci, voici mon code :

    ViewController.hh
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #import <UIKit/UIKit.h>
     
    @interface ViewController : UIViewController
     
    - (cv::Mat)cvMatFromUIImage<img src="images/smilies/icon_sad.gif" border="0" alt="" title=":(" class="inlineimg" />UIImage *)image;
    - (cv::Mat)cvMatGrayFromUIImage<img src="images/smilies/icon_sad.gif" border="0" alt="" title=":(" class="inlineimg" />UIImage *)image;
    - (UIImage *)UIImageFromCVMat<img src="images/smilies/icon_sad.gif" border="0" alt="" title=":(" class="inlineimg" />cv::Mat)cvMat;
     
    @end


    Et ViewController.mm
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #import "ViewController.hh"
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (cv::Mat)cvMatFromUIImageUIImage *)image
    {
        @@@
    }
    
    - (cv::Mat)cvMatGrayFromUIImageUIImage *)image
    {
        @@@
    }
    
    -(UIImage *)UIImageFromCVMatcv::Mat)cvMat
    {
        @@@
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	// Do any additional setup after loading the view, typically from a nib.
        NSString* filename = [[NSBundle mainBundle] pathForResource:@"openCV" ofType:@"jpg"];
        UIImage *image = [UIImage imageWithContentsOfFile:filename];
        cv::Mat inputMat = cvMatFromUIImage(image);//Bug ici
        UIImage *newImage = UIImageFromCVMat(inputMat);//et ici
        
        self.view.backgroundColor = [UIColor colorWithPatternImage:newImage];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"HelloWorld !" message:@"Welcome to OpenCV !" delegate:self cancelButtonTitle:@"Continue" otherButtonTitles:nil, nil];
        [alert show];
    }
    
    - (void)viewDidUnload
    {
        [super viewDidUnload];
        // Release any retained subviews of the main view.
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientationUIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    }
    
    @end


    Avec les zones en rouge les zones ayant des erreurs.
    Les 2 erreurs sont les mêmes.

    C'est quoi le soucis maintenant ?

    Merci

  5. #5
    Membre expert
    Citation Envoyé par Tiffado Voir le message

    cv::Mat inputMat = cvMatFromUIImage(image);//Bug ici
    UIImage *newImage = UIImageFromCVMat(inputMat);//et ici
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    … [self cvMatFromUIImage:image] ;
    …