看网上方法很多,但版本都不够新,我看了网上一些知识,总结了下,来个最新版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. java:集合的自定义多重排序

    问题: 有一个乱序的对象集合,要求先按对象的属性A排序(排序规则由业务确定,非A-Z或0-9的常规顺序),相同A属性的记录,按根据属性B排序(排序规则,同样由业务确定,非常规顺序) -前提:业务规则是 ...

  2. canvas drag 实现拖拽拼图小游戏

    博主一直心心念念想做一个小游戏-  前端时间终于做了一个小游戏,直到现在才来总结,哈哈- 以后要勤奋点更新博客! 实现原理 1.如何切图? 用之前的方法就是使用photoshop将图片切成相应大小的图 ...

  3. requirejs:性能优化-及早并行加载

    为了提高页面的性能,通常情况下,我们希望资源尽可能地早地并行加载.这里有两个要点,首先是尽早,其次是并行. 通过data-main方式加载要尽可能地避免,因为它让requirejs.业务代码不必要地串 ...

  4. MD5算法的C语言实现

    1 #include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h ...

  5. 利用manifest文件对程序目录下的dll进行分类

    1 背景 对于大部分的券商和机构投资者,只能通过有交易所交易系统接入资质的券商提供的柜台系统来进行现货交易.相对于期货市场,现货市场的柜台系统千差万别,接入协议有明文字符串.二进制数据和FIX协议等, ...

  6. 【BZOJ1002】【FJOI2007】轮状病毒(生成树计数)

    1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1766  Solved: 946[Submit][Status ...

  7. 用户 'IIS APPPOOL\***' 登录失败

    用户 'IIS APPPOOL\DefaultAppPool' 登录失败. 我在windows8中安装了iis之后添加了我做的网站打开之后提示用户 'IIS APPPOOL\DefaultAppPoo ...

  8. eclipse中的常用插件

    常用插件整理: http://blog.sina.com.cn/s/blog_60b5e13e0102vz6q.html    插件带有链接 http://blog.csdn.net/kagoy/ar ...

  9. Maven的生命周期和插件

    首先解释下maven build等 Maven build是这个插件让你自己去配置执行目标的.Maven clean 清除上一次Maven执行的结果Maven generate-sources会根据p ...

  10. IntelliJ_设置

    1.修改背景色.修改字体大小 http://blog.csdn.net/hpf911/article/details/16888797 2.显示行号 搜索Line Number 3.代码结构图 Vie ...