看网上方法很多,但版本都不够新,我看了网上一些知识,总结了下,来个最新版Xcode6.1的.

最近主要想做iOS端的车牌识别,所以开始了解OpenCV。有兴趣的可以跟我交流下哈。

一.Opencv的使用:

  步骤:

  1.从官网下载iOS版本的Opencv2.framework。

  2.拖进工程,选择copy items if needed

  3.进入building settings,设置Framework SearchPath:

     设置成$(PROJECT_DIR)/Newtest,这个Newtest是你的项目名,主要是为了定位到你存放的Opencv2.framework所在位置。

  4.使用Opencv的方式:第(1)种全局pch:(不推荐)新建pch文件,修改成:

              #ifdef __cplusplus

              #import <opencv2/opencv.hpp>

              #endif

                并在building setting里的 Incease Sharing of Precompiled Headers项目处:

               设置成$(PROJECT_DIR)/Newtest,同理,这个Newtest是你的项目名,主要是为了定位到你存放的PCH文件所在位置。

              PCH文件以前建工程默认生成,是全局性质的import。Xcode6不再自动生成。苹果引导开发者在某个类要用时才用。

             第(2)种:在需要的地方#import <opencv2/opencv.hpp>

                这里的重点是:使用opencv的类名一定要改成.mm!!

                        比如你专门写了各一个处理图片的类,Imageprocess。可以在.h里加入。

二:灰度化和二值化的主要实现过程:

  其实过程就是这样:

  UIImage(iOS图像类)-> cv::Mat(OpenCV图像类) -> Opencv灰度或二值处理函数 -> UIImage

三:Opencv类Imageprocess代码参考:

Imageprocess.h

//
// Imageprocess.h
// Chepaishibie
//
// Created by shen on 15/1/28.
// Copyright (c) 2015年 shen. All rights reserved.
// #import <Foundation/Foundation.h>
#import <opencv2/opencv.hpp>
#import <UIKit/UIKit.h> @interface Imageprocess : UIViewController - (cv::Mat)cvMatFromUIImage:(UIImage *)image; - (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat; - (IplImage *)CreateIplImageFromUIImage:(UIImage *)image; - (UIImage *)UIImageFromIplImage:(IplImage *)image; - (UIImage *)Grayimage:(UIImage *)srcimage; - (UIImage *)Erzhiimage:(UIImage *)srcimage; int Otsu(unsigned char* pGrayImg , int iWidth , int iHeight); @end

Imageprocess.mm 里面包含了很多函数:

主要是 UIImage->cv::Mat ,cv::Mat->UIImage,UIImage->IplImage,IplImage->UIImage, 灰度化,二值化等,还有个OSTU计算阈值的方法。

//
// Imageprocess.mm
// Chepaishibie
//
// Created by shen on 15/1/28.
// Copyright (c) 2015年 shen. All rights reserved.
// #import "Imageprocess.h" @implementation Imageprocess #pragma mark - opencv method
// UIImage to cvMat
- (cv::Mat)cvMatFromUIImage:(UIImage *)image
{
CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
CGFloat cols = image.size.width;
CGFloat rows = image.size.height; cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to data
cols, // Width of bitmap
rows, // Height of bitmap
, // Bits per component
cvMat.step[], // Bytes per row
colorSpace, // Colorspace
kCGImageAlphaNoneSkipLast |
kCGBitmapByteOrderDefault); // Bitmap info flags CGContextDrawImage(contextRef, CGRectMake(, , cols, rows), image.CGImage);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace); return cvMat;
} // CvMat to UIImage
-(UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{
NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];
CGColorSpaceRef colorSpace; if (cvMat.elemSize() == ) {
colorSpace = CGColorSpaceCreateDeviceGray();
} else {
colorSpace = CGColorSpaceCreateDeviceRGB();
} CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); // Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
cvMat.rows, //height
, //bits per component
* cvMat.elemSize(), //bits per pixel
cvMat.step[], //bytesPerRow
colorSpace, //colorspace
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
provider, //CGDataProviderRef
NULL, //decode
false, //should interpolate
kCGRenderingIntentDefault //intent
); // Getting UIImage from CGImage
UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace); return finalImage;
} //由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构。
// NOTE you SHOULD cvReleaseImage() for the return value when end of the code.
- (IplImage *)CreateIplImageFromUIImage:(UIImage *)image {
// Getting CGImage from UIImage
CGImageRef imageRef = image.CGImage; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Creating temporal IplImage for drawing
IplImage *iplimage = cvCreateImage(
cvSize(image.size.width,image.size.height), IPL_DEPTH_8U,
);
// Creating CGContext for temporal IplImage
CGContextRef contextRef = CGBitmapContextCreate(
iplimage->imageData, iplimage->width, iplimage->height,
iplimage->depth, iplimage->widthStep,
colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault
);
// Drawing CGImage to CGContext
CGContextDrawImage(
contextRef,
CGRectMake(, , image.size.width, image.size.height),
imageRef
);
CGContextRelease(contextRef);
CGColorSpaceRelease(colorSpace); // Creating result IplImage
IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, );
cvCvtColor(iplimage, ret, CV_RGBA2BGR);
cvReleaseImage(&iplimage); return ret;
} // NOTE You should convert color mode as RGB before passing to this function
- (UIImage *)UIImageFromIplImage:(IplImage *)image {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// Allocating the buffer for CGImage
NSData *data =
[NSData dataWithBytes:image->imageData length:image->imageSize];
CGDataProviderRef provider =
CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
// Creating CGImage from chunk of IplImage
CGImageRef imageRef = CGImageCreate(
image->width, image->height,
image->depth, image->depth * image->nChannels, image->widthStep,
colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault,
provider, NULL, false, kCGRenderingIntentDefault
);
// Getting UIImage from CGImage
UIImage *ret = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return ret;
} #pragma mark - custom method // OSTU算法求出阈值
int Otsu(unsigned char* pGrayImg , int iWidth , int iHeight)
{
if((pGrayImg==)||(iWidth<=)||(iHeight<=))return -;
int ihist[];
int thresholdValue=; // „–÷µ
int n, n1, n2 ;
double m1, m2, sum, csum, fmax, sb;
int i,j,k;
memset(ihist, , sizeof(ihist));
n=iHeight*iWidth;
sum = csum = 0.0;
fmax = -1.0;
n1 = ;
for(i=; i < iHeight; i++)
{
for(j=; j < iWidth; j++)
{
ihist[*pGrayImg]++;
pGrayImg++;
}
}
pGrayImg -= n;
for (k=; k <= ; k++)
{
sum += (double) k * (double) ihist[k];
}
for (k=; k <=; k++)
{
n1 += ihist[k];
if(n1==)continue;
n2 = n - n1;
if(n2==)break;
csum += (double)k *ihist[k];
m1 = csum/n1;
m2 = (sum-csum)/n2;
sb = (double) n1 *(double) n2 *(m1 - m2) * (m1 - m2);
if (sb > fmax)
{
fmax = sb;
thresholdValue = k;
}
}
return(thresholdValue);
} -(UIImage *)Grayimage:(UIImage *)srcimage{
UIImage *resimage; //openCV二值化过程: /*
//1.Src的UIImage -> Src的IplImage
IplImage* srcImage1 = [self CreateIplImageFromUIImage:srcimage]; //2.设置Src的IplImage的ImageROI
int width = srcImage1->width;
int height = srcImage1->height;
printf("图片大小%d,%d\n",width,height); // 分割矩形区域
int x = 400;
int y = 1100;
int w = 1200;
int h = 600; //cvSetImageROI:基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvSetImageROI(srcImage1, cvRect(x, y, w , h)); //3.创建新的dstImage1的IplImage,并复制Src的IplImage
IplImage* dstImage1 = cvCreateImage(cvSize(w, h), srcImage1->depth, srcImage1->nChannels);
//cvCopy:如果输入输出数组中的一个是IplImage类型的话,其ROI和COI将被使用。
cvCopy(srcImage1, dstImage1,0);
//cvResetImageROI:释放基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvResetImageROI(srcImage1); resimage = [self UIImageFromIplImage:dstImage1];
*/ //4.dstImage1的IplImage转换成cvMat形式的matImage
cv::Mat matImage = [self cvMatFromUIImage:srcimage]; cv::Mat matGrey; //5.cvtColor函数对matImage进行灰度处理
//取得IplImage形式的灰度图像
cv::cvtColor(matImage, matGrey, CV_BGR2GRAY);// 转换成灰色 //6.使用灰度后的IplImage形式图像,用OSTU算法算阈值:threshold
//IplImage grey = matGrey; resimage = [self UIImageFromCVMat:matGrey]; /*
unsigned char* dataImage = (unsigned char*)grey.imageData;
int threshold = Otsu(dataImage, grey.width, grey.height);
printf("阈值:%d\n",threshold); //7.利用阈值算得新的cvMat形式的图像
cv::Mat matBinary;
cv::threshold(matGrey, matBinary, threshold, 255, cv::THRESH_BINARY); //8.cvMat形式的图像转UIImage
UIImage* image = [[UIImage alloc ]init];
image = [self UIImageFromCVMat:matBinary]; resimage = image;
*/ return resimage;
} -(UIImage *)Erzhiimage:(UIImage *)srcimage{ UIImage *resimage; //openCV二值化过程: /*
//1.Src的UIImage -> Src的IplImage
IplImage* srcImage1 = [self CreateIplImageFromUIImage:srcimage]; //2.设置Src的IplImage的ImageROI
int width = srcImage1->width;
int height = srcImage1->height;
printf("图片大小%d,%d\n",width,height);
// // 分割矩形区域
int x = 400;
int y = 1100;
int w = 1200;
int h = 600; //cvSetImageROI:基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvSetImageROI(srcImage1, cvRect(x, y, w , h)); //3.创建新的dstImage1的IplImage,并复制Src的IplImage
IplImage* dstImage1 = cvCreateImage(cvSize(w, h), srcImage1->depth, srcImage1->nChannels);
//cvCopy:如果输入输出数组中的一个是IplImage类型的话,其ROI和COI将被使用。
cvCopy(srcImage1, dstImage1,0);
//cvResetImageROI:释放基于给定的矩形设置图像的ROI(感兴趣区域,region of interesting)
cvResetImageROI(srcImage1); resimage = [self UIImageFromIplImage:dstImage1];
*/ //4.dstImage1的IplImage转换成cvMat形式的matImage
cv::Mat matImage = [self cvMatFromUIImage:srcimage]; cv::Mat matGrey; //5.cvtColor函数对matImage进行灰度处理
//取得IplImage形式的灰度图像
cv::cvtColor(matImage, matGrey, CV_BGR2GRAY);// 转换成灰色 //6.使用灰度后的IplImage形式图像,用OSTU算法算阈值:threshold
IplImage grey = matGrey;
unsigned char* dataImage = (unsigned char*)grey.imageData;
int threshold = Otsu(dataImage, grey.width, grey.height);
printf("阈值:%d\n",threshold); //7.利用阈值算得新的cvMat形式的图像
cv::Mat matBinary;
cv::threshold(matGrey, matBinary, threshold, , cv::THRESH_BINARY); //8.cvMat形式的图像转UIImage
UIImage* image = [[UIImage alloc ]init];
image = [self UIImageFromCVMat:matBinary]; resimage = image; return resimage;
} @end

四:可能问题:

  1.出现'list' file not found:   检查类名是否改成.mm了!还不行的话,在Build Phases 中加入库:libc++.dylib 试试。

  2.arm64不支持的问题:在Building settings里Build Active Architecture Only改为No,然后下面Valid Architectures把arm64删了。

五:样例参考:有两个很好的例子,一个是二值,一个是图像匹配。

1.二值 https://github.com/zltqzj/ios_opencv_divide

2.图像匹配 https://github.com/jimple/OpenCVSample

[iOS OpenCV的使用,灰度和二值化]的更多相关文章

  1. OpenCV图像的全局阈值二值化函数(OTSU)

    cv::threshold(GrayImg, Bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);//灰度图像二值化 CV_THRESH_OTSU是提取图像最 ...

  2. OpenCV中对图像进行二值化的关键函数——cvThreshold()。

    函数功能:采用Canny方法对图像进行边缘检测 函数原型: void cvThreshold( const CvArr* src, CvArr* dst, double threshold, doub ...

  3. VB6之图像灰度与二值化

    老代码备忘,我对图像处理不是太懂. 注:部分代码引援自网上,话说我到底自己写过什么代码... Private Declare Function GetBitmapBits Lib "gdi3 ...

  4. opencv 对RGB图像直接二值化

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  5. opencv中对图片的二值化操作并提取特定颜色区域

    一.最近因为所在的实习公司要求用opencv视觉库来写一个对图片识别并提取指定区域的程序.看了很多资料,只学会了皮毛,下面附上简单的代码.运行程序之前需要安装opencv库,官网地址为:https:/ ...

  6. Java基于opencv实现图像数字识别(三)—灰度化和二值化

    Java基于opencv实现图像数字识别(三)-灰度化和二值化 一.灰度化 灰度化:在RGB模型中,如果R=G=B时,则彩色表示灰度颜色,其中R=G=B的值叫灰度值:因此,灰度图像每个像素点只需一个字 ...

  7. OpenCV图像的二值化

    图像的二值化: 与边缘检测相比,轮廓检测有时能更好的反映图像的内容.而要对图像进行轮廓检测,则必须要先对图像进行二值化,图像的二值化就是将图像上的像素点的灰度值设置为0或255,这样将使整个图像呈现出 ...

  8. opencv图像二值化的函数cvThreshold()。 cvAdaptiveThreshol

    OpenCV中对图像进行二值化的关键函数——cvThreshold(). 函数功能:采用Canny方法对图像进行边缘检测 函数原型: void cvThreshold( const CvArr* sr ...

  9. opencv-python图像二值化函数cv2.threshold函数详解及参数cv2.THRESH_OTSU使用

    cv2.threshold()函数的作用是将一幅灰度图二值化,基本用法如下: #ret:暂时就认为是设定的thresh阈值,mask:二值化的图像 ret,mask = cv2.threshold(i ...

随机推荐

  1. echo使用说明,参数详解

    简介 echo [OPTION]... [STRING]... 描述 -n 末尾不加换行 -e 开启输出字串中对反斜杠的转译 -E 禁用反斜杠转译 只有开启-e参数的时候,下面的命令才能起作用: \0 ...

  2. rpc框架之 thrift 学习 1 - 安装 及 hello world

    thrift是一个facebook开源的高效RPC框架,其主要特点是跨语言及二进制高效传输(当然,除了二进制,也支持json等常用序列化机制),官网地址:http://thrift.apache.or ...

  3. 【位运算经典应用】 N皇后问题

    说到位运算的经典应用,不得不说N皇后问题. 学过程序设计的都知道N皇后问题,没听过也没关系.很简单,最传统的的N皇后问题是这个样子的,给你一个n * n大小的board,让你放n个皇后(国际象棋),要 ...

  4. ALinq Dynamic 使用指南——前言

    一.简介 ALinq Dynamic 为ALinq以及Linq to SQL提供了一个Entiy SQL的查询接口,使得它们能够应用Entity SQL 进行数据的查询.它的原理是将Entiy SQL ...

  5. 利用PhotoShop将Font-Awesome转为图片格式

    介绍如何将Font-Awesome等字体图标转换为图片格式,使用PHOTPSHOP很简单. 网上找了很多,都比较麻烦.别问为什么要这么做,因为你还没遇到需要的时候. 下载Font-Awesome字体库 ...

  6. matlab eps

    matlab eps eps是一个函数.当没有参数时默认参数是1.返回的是该参数的精度. 也就是说单个的eps实际上是eps(1),表示的是1的精度. 这里要说一下精度的概念.浮点数所能表示的数值范围 ...

  7. memcached安装配置

    简述: memcached,开源的分布式缓存数据系统.高性能的NOSQL . Linux 一.环境配置与安装 01.编译准备环境 yum install -y gcc make cmake autoc ...

  8. Linux中TFTP使用详解

    FTP协议简介TFTP是用来下载远程文件的最简单网络协议,它其于UDP协议而实现. linux服务器端tftp-server的配置1.安装tftp服务器需要安装xinetd(守护tftp).tftp和 ...

  9. webpack进阶之插件篇

    一.插件篇 1. 自动补全css3前缀 autoprefixer 官方是这样说的:Parse CSS and add vendor prefixes to CSS rules using values ...

  10. 1109关于redo_Log和undo_log和BIN-LOG

    转自http://www.cnblogs.com/Bozh/archive/2013/03/18/2966494.html 三者之间的区别BIN-LOG 一个对应BINLOG文件REDO-LOG 对应 ...