1

does anyone know if it is possible to pass an array of CGPoint from objective c++ to swift?

I am able to pass CGPoint back to swift. However, I was not able to figure out how to pass the value back as an array.

Here is the code I used to pass it back to swift.

OpenCVWrapper.mm

+(CGPoint) detectCircle:(UIImage *)image
{
CGPoint pointArray;

cv::Mat img;
UIImageToMat(image, img);

cv::Mat grayMat;
cvtColor(img, grayMat, CV_BGR2GRAY);

cv::Mat dilateMat;
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(7,7));
cv::morphologyEx(grayMat, dilateMat, cv::MORPH_OPEN, kernel);

cv::Mat cannyMat;
Canny(dilateMat, cannyMat, 10, 100);

cv::Mat guassianMat;

cv::GaussianBlur(cannyMat, guassianMat, cv::Size(11,13), 0);

std::vector<cv::Vec3f> circleMat;
cv::HoughCircles(guassianMat, circleMat, CV_HOUGH_GRADIENT, 1, cannyMat.rows / 15,120, 10, 0, 30);

cv::Mat houghCircles;
houghCircles.create(guassianMat.rows, guassianMat.cols, CV_8UC1);

for( size_t i = 0; i < circleMat.size(); i++ )
{
    cv::Vec3i parameters = circleMat[i];
    double x, y;
    int r;

    x = parameters[0];
    y = parameters[1];
    r = int(parameters[2]);

    pointArray.x = x;
    pointArray.y = y;

}


return pointArray;
}

OpenCVWrapper.h

+(CGPoint) detectCircle: (UIImage *)image;

viewController.Swift

@IBAction func detectBtn(_ sender: Any) {
    var points : CGPoint = OpenCVWrapper.detectCircle(adjustBtightnessImage)
    print(points)

}
K Y
  • 39
  • 7
  • 1
    You can create an `NSArray` containing `NSValue`s, if the array does not contain too many elements. Or else, you can pass the address of the first element as an `UnsafePointer` (`CGPoint *` in ObjC++), in this case, the number of elements should also be passed. – OOPer Oct 01 '18 at 03:13
  • Hi @OOPer I am not sure is this is what you mean by UnsafePointer but I have tried to use `std::vector` as a return and use `var points : [UnsafeMutablePointer] = [OpenCVWrapper.detectCircle(adjustBtightnessImage) as! UnsafeMutablePointer]` to get the data but I just get "Thread 1: EXC_BREAKPOINT" error. do you have a sample code or something I can look at for `UnsafePointer` ? – K Y Oct 01 '18 at 06:09
  • Without knowing what you returned from your `detectCircle(_:)`, I cannot comment anything sure. But usually `as!` casting does not make what you expect. And I cannot show you any code as you are not showing any code having an array of `CGPoint`. – OOPer Oct 01 '18 at 06:14
  • @KY Swift only supports bridging Objective-C. If you want to use C++, you must ensure that it is not imported in the bridge file. See this answer for details: https://stackoverflow.com/a/32554229/1644934 – Vincent Sit Oct 01 '18 at 07:07
  • @Vincent Thank you for your concern I am able to use C++ without an issue – K Y Oct 01 '18 at 08:19
  • @OOPer Thank you for your comment I was able to solve my issue with the help from your comment and Vincent answer – K Y Oct 01 '18 at 08:22
  • Thanks for reporting. And happy to hear you could have solved your issue. I would write an answer myself, when you post a new issue with easily reusable code, maybe next chance. – OOPer Oct 01 '18 at 08:35

1 Answers1

4

The best way to do this is to use NSValue to wrap it as @OOPer said.

The main reason is that CGPoint is not an object type in Objective-C. You can't put it directly in an NSArray. You need to wrap it in NSValue.

// Objective-C
+ (NSArray<NSValue *> *)detectCircle:(UIImage *)image {
  return @[
           [NSValue valueWithCGPoint:CGPointMake(10, 10)],
           [NSValue valueWithCGPoint:CGPointMake(10, 20)]
           ];
}

// swift
let points = Circle.detect(UIImage()).map { $0.cgPointValue }
Vincent Sit
  • 2,214
  • 1
  • 24
  • 27
  • Thank you @Vincen this answer did help but in the cause of my code it will be more suitable to use NSMutableArray – K Y Oct 01 '18 at 08:24
  • @KY No problem, I am very happy to help you. Just modify it according to your needs. – Vincent Sit Oct 01 '18 at 10:19