How did Miss Cang get his code

— initial experience with OpenCV, Swift and C++

Updates

  • October 27, 2017 first draft of V1.0
  • Oct 28, 2017 V1.1 added Objective-C++ compilation methods

When it comes to OpenCV, I believe most people have heard of it. The application field is very wide, and the development of C++ is naturally cross-platform. Once we learn it, we can use it on various platforms. And to achieve a simple Mosaic function development environment: Swift4, XCode 9.0

1. What is OpenCV?

  • Intel corporation initiated and participated in the development in 1999, has 18 years of history
  • OpenCV stands for Open Source Computer Vision Library
  • Is a cross-platform open source computer vision library for developing real-time image processing, computer vision, and pattern recognition programs.
  • supportC/C++,Java,Python,OC,Swift,RubyLanguage, etc.
  • supportWindows,Android,Maemo,FreeBSD,OpenBSD,iOS,LinuxandMac OS

2, difficult points, ideas

  • Because we’re usingSwift, as it is not available at presentSwiftThe use ofC++Class, so we have to think of a method inSwiftIn the callC++The class of
  • It’s actually quite simple,SwiftBorn with heelObjective-C++The ability to mix, andObjective-C++It can be used directly insideC++Class, the above problem will be solved

3. Mosaic principle

  • In fact, turn down the pixel density of the picture to create a Mosaic effect
  • Before you start to make a Mosaic, you need to set a Mosaic level, which means that every few pixels in the original image become one pixel in the new image
  • Take a pixel in the upper left corner of a small area and fill it with the entire small area
  • As shown in the picture below, the left is the original picture and the right is the transformed picture. Assuming that the Mosaic level is 3, the area represented by each number is a small unit for processing. Take the color of the upper left corner of the smallest unit and fill the whole small unit

4. Start the project

4.1. Set up c++ and swift co-programming environment

We first need to build a c++ environment, and then c++ development, and c++ environment can be verified by iostream cout function

  1. First, we usexCodeCreate a newswifttheiOSproject
  2. Within the project, create a new oneObjective-CClass, inheritance,NSObject, it will automatically prompt you to add a bridge file to the projectSwiftexposedObjective-CMethods)
  3. Because we’re going to use Objective-C++, and there are two ways to turn Objective-C into Objective-C++

    • the.mThe file name suffix is changed.mm, xCode will automatically recognize our code asObjective-C++The (xCodeAutomatically identify source file type by suffix)
    • Select the.m file you want to modify and change the Type property on the right to: Objective-C++ Source (you can also manually specify the Source file Type)

  4. In the.mm file, add a test method to test whether the C++ environment is set up successfully

    #import "myutil. h" #import <iostream> @implementation MyUtil + (void)testCpp { cout << "Hello Swift and Cpp" << endl; }Copy the code
  5. Expose our test method header file in the bridge file that xCode created automatically earlier

  6. Call the test method in Swift, and the console prints “Hello Swift and Cpp”

    import UIKit class ViewController: UIViewController {override func viewDidLoad() {super.viewdidLoad () // myutil.testcpp ()}Copy the code

4.3 import OpenCV dynamic library

Importing OpenCV libraries in iOS development is actually very easy, just drag and drop into the project file

  1. First of all toOpenCVthewebsiteDownload what we needframework, download address:Opencv.org/releases.ht…, select the latest versioniOS packCan be
  2. Download it and unzip it, then drag it to our project directory and set it as shown below

  3. Set up our project linkOpenCVThe dynamic library

  4. Build to make sure no errors are reported

4.4. Implement Mosaic functions

Now it’s time to work on the code

  1. The first step is to import the OpenCV header file in the.m file. After importing the header file, the code looks like this.

    • Don’t in.hFile to importOpenCVError message:Core.hpp header must be compiled as C++, see this problem, quickly move the head file to.mfile
    • Also,OpenCVThe header file is best placed in#import <UIKit/UIKit.h>Before, otherwise will also report an error:enum { NO, FEATHER, MULTI_BAND }; Expected identifier
    #import <opencv2/imgcodecs/ios.h> // Import matrix helper class #import <opencv2/highgui.hpp> #import <opencv2/core/types.hpp> #import "myutil. h" #import <iostream> using namespace std; using namespace cv;Copy the code
  2. Implement Mosaic functions

    +(UIImage*)opencvImage:(UIImage*)image level:(int)level{ UIImageToMat(image, mat_image_src); Int width = mat_image_src.cols; int width = mat_image_src.cols; int height = mat_image_src.rows; ARGB->RGB Mat mat_image_dst; ARGB->RGB Mat mat_image_dst; cvtColor(mat_image_src, mat_image_dst, CV_RGBA2RGB, 3); Mat_image_clone = mat_image_dst.clone(); Int xMax = width - level; int yMax = height - level; for (int y = 0; y <= yMax; y += level) { for (int x = 0; x <= xMax; X += level) {mat_image_clone.at<Vec3b>(I, (j) - > pixel color values of multiple) - > - > ARGB - > / / mat_image_clone array. At < Vec3b > (I, j) [0] - > R value / / mat_image_clone. At < Vec3b > (I, Mat_image_clone. At <Vec3b>(I, j)[2]->B value mat_image_clone.at<Vec3b>(y, x)[1], mat_image_clone.at<Vec3b>(y, x)[2]); Rect2i mosaicRect = rect2 (x, y, level, level); Mat roi = mat_image_dst(mosaicRect); //CV_: represents the framework namespace //8 represents: 32 bit color ->ARGB->8 bits = 1 byte -> 4 bytes //U: Unsigned type //C analysis: char type //3表 : 3 channels ->RGB Mat roiCopy = Mat(Mosaicrect.size (), CV_8UC3, scalar); roiCopy.copyTo(roi); OpenCV ->iOS image return MatToUIImage(mat_image_dst); }Copy the code

4.5 call the Mosaic function in Swift

Now that the function is implemented, it’s time to call it from Swift

  1. For the sake of testing, we’re instoryboardTo create a simple interface, switch between the Mosaic picture and the original picture in the button, the interface is as follows:

  2. Call the above Mosaic function in the button click event

    @IBOutlet weak var imageView: UIImageView! @ibAction Func origImageBtnClick(_ sender: Any) {imageview. image = UIImage(named: } @ibAction func mosaicImageBtnClick(_ sender: Any) { guard let origImage = imageView.image else { return } let mosaicImage = MyUtil.opencvImage(origImage, level: 20) imageView.image = mosaicImage }Copy the code
  3. The effect is as follows, the left is the original picture, the right is the Mosaic after the picture, so, cang teacher’s code hit up ~

5, afterword.

For c + +, a lot of people is not strange, but I think for iOS developers, not a lot of children’s shoes used c + +, I’ve been worship of the great god c + +, because by c + +, we can easily realize cross-platform development, for our today’s Mosaic code, ported to the android platform, the contents and only need to do a small part of the change, It can be perfectly adapted (of course, android development environment is not as simple as iOS), so it is very cost-effective to master and use C++.

github
Github.com/fengqiangbo…
OpenCV.framework
Star