9月 142013
 

Your ads will be inserted here by

Easy AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

通过访问像素来进行二值化处理

int main()
{
    IplImage *src = cvLoadImage("D:/1.jpg");  
	IplImage *dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U,1);
	CvSize size = cvGetSize(src);
	CvScalar s;
	if(src==NULL)
	{
		printf("Load failed!\n");
	    return -1;
	}
	//(int i;i<src.)
	//cvCvtColor(src,dst,CV_BGR2GRAY);
	for(int i=0;i<size.height;i++)
		for(int j=0;j<size.width;j++)
		{
		    s=cvGet2D(src,i,j);
			double tmp = (s.val[0]+s.val[1]+s.val[2])/3;
			if(tmp > 128)
				s.val[0]=s.val[1]=s.val[2] = 255;
			else if(tmp <= 128)
				s.val[0]=s.val[1]=s.val[2] = 0;			
			cvSet2D(dst,i,j,s);
		}
	cvNamedWindow("Image", 1);
	cvShowImage("Image", dst);
	cvWaitKey(0);

	cvDestroyWindow("Image");
	cvReleaseImage(&dst);
	cvReleaseImage(&src);
	return 0;
}
4月 142013
 

Your ads will be inserted here by

Easy AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

假设要访问第k通道、第i行、第j列的像素
cvGet2D用于获取对应点的数据
cvSet2D用于设置对应点的数据
s.val(i)
获取i通道的值
s.val(i,data)
设置i通道的值为data

public class test { 
    public static void main(String args[]){ 
    IplImage img = cvLoadImage("D:\\car.bmp",3); 
    if (null == img)//如果读入失败,退出程序 
    System.exit(1); 
    /*创建一个单通道的图像*/
    IplImage imgc = cvCreateImage(cvSize(img.width(),img.height()),IPL_DEPTH_8U,0);
    /*
    CvScalar就是一个可以用来存放4个double数值的数组;一般用来存放像素值(不一定是灰度值哦)的,最多可以存
    放4个通道的。
    typedef struct CvScalar
    {
      double val[4];
      }CvScalar; 
    */
    CvScalar s,to=null;
    int i=10,j=5;
    s = cvGet2D(img,i,j); //注意i表示y坐标,j表示x坐标
    System.out.printf("intensity=%f\n",s.val(0));
    cvCvtColor(img,imgc,CV_BGR2GRAY);
    for(i=0;i<img.height();i++)
        for(j=0;j<img.width();j++)
        {  
            /*灰度变换
            s = cvGet2D(img,i,j); 
            to = cvGet2D(imgc,i,j);
            to.val(0,(int)(s.val(0)*0.114+s.val(1)*0.587+s.val(2)*0.299));
            cvSet2D(imgc,i,j,s);//写到图片里
            */
            /*二值化处理*/
            s = cvGet2D(imgc,i,j);
            if(s.val(0)&gt;100)
            {
                s.val(0,256); 
            }
            else
            {
                s.val(0,0); 
            }
        cvSet2D(imgc,i,j,s);//写到图片里 
        }

    s = cvGet2D(img,5,10);
    System.out.printf("intensity=%f\n",s.val(0));
    //创建一个窗口,标题为Example 
    cvNamedWindow("Example",CV_WINDOW_AUTOSIZE); 
    //在窗口Example中显示图片
    cvShowImage("Example",imgc); 
    //暂停程序,等待用户触发一个按键
    cvWaitKey(0); 
    //释放图像所分配的内存 
    cvReleaseImage(imgc); 
    //销毁窗口 
    cvDestroyWindow("Example"); 
} 

}

对数变换

s = cvGet2D(img,i,j);
s.val(0,Math.log(s.val(0)));
cvSet2D(imgc,i,j,s);//写到图片里
4月 142013
 

Your ads will be inserted here by

Easy AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

一、读取图像

im = imread(‘filename’)

读取灰度图像

一个8位的灰度图像的每一个像素只有一个字节来记录,所在调用imread后返回的结果是一个uint8型的二维数组,第一维代表的是行,第二维代表的是列。

im = imread(‘filename’)

读取RGB图像

RGB图像由于有三个通道的信息,返回的是uint8型的三维数组,其中第一维代表的是行,第二维代表的是列,第三维代表的是一个颜色通道,对于RGB来说,第三维的大小一定为3,可以通过(:, :, 1)来取出红色通道的颜色信息,(:, :, 2)是绿色通道。调用格式和灰度图像相同,都是:

im = imread(‘filename’)

调用imfinfo函数来观察图像的信息

imfinfo(‘filename’)

二、图像类型转

真彩图像→索引图像

X=dither(RGB,map)

节省存储空间,假彩色

索引图像→真彩图像

RGB=ind2rgb(X,map)

便于图像处理

真彩图像→灰度图像

I=rgb2gray(RGB)

得到亮度分布

真彩图像→二值图像

BW=im2bw(RGB,level)

阈值处理,筛选

索引图像→灰度图像

I=ind2gray(X,map)

Newmap=rgb2gray(map)

得到亮度分布

灰度图像→索引图像

[X,map]=gray2ind(I,n),

X=grayslice(I,n)

X=grayslice(I,v)

伪彩色处理

灰度图像→二值图像

BW=dither(I)

BW=im2bw(I,level)

阈值处理,筛选

索引图像→二值图像

BW=im2bw(X,map,level)

阈值处理,筛选

数据矩阵→灰度图像

I=mat2gray(A,[max,min])

I=mat2gray(A)

产生图像

y = ind2gray(x, map); %索引图像转换为灰度图像

[y, map] = gray2ind(x); %灰度图像转换为索引图像

y = rgb2gray(x); %RGB图像转换为灰度图像

[y, map] = rgb2ind(x, n); %RGB图像转换为索引图像

y = ind2rgb(x, map); %索引图像转换为RGB图像

三、图像存储imwrite

imwrite(im, ‘filename’, ‘format’);

format 可以为PNG,BMP,GIF

索引图像

imwrite(im, immap, ‘filename’, ‘format’);

四、图像显示

1、image

image是最原始的显示图像的函数,对于灰度图像

image(im), truesize, axis off, colormap(gray(256));

这里truesize显示图像和实际大小相同,axis off去掉了坐标轴,gray(256)是将0到1之间分出256个不同的灰度,正好对应的灰度图像的范围

如果是彩色图像,就不需要colormap这个参数了,直接调用image即可正常显示。

2、imshow

imshow也可以用来显示图像,如果传入数据是原始的uint8类型的,不管是灰度图像和RGB图像都可以直接正常显示。不过如果将数据直接转为double类型,图像就无法正常显示,因为当传入double类型的时候,函数会认为0代表黑,1.0代表白,所以一般情况下这种错误操作很可能显示一幅全白图像。

为了避免自己转换类型出错,可以使用im2double或im2uint8函数,这样不管数据范围是0到255还是0到1都可以正确地进行数据转换。

im = imread(‘cameraman.tif’);

subplot(1, 3, 1);

imshow(im);

subplot(1, 3, 2);

imshow(im2double(im));

subplot(1, 3, 3);

imshow(im2double(double(im) / 256));

五、图像的缩放imresize

利用imresize(im, scale, method)或imresize(im, [row col], method)

method控制的就是插值的方法:bicubic  bilinear  nearest

六、点处理Point Processing

1、算术操作 Arithmetic operations

主要是加减乘除处理

im = imread(‘lena.jpg’);
im1 =imadd(im,128);
im2 = imsubtract(im,128);
im3 = immultiply(im,2);
im4 = imdivide(im,2);
subplot(2, 2, 1);
imshow(im1);
title(‘Add’);
subplot(2, 2, 2);
imshow(im2);
title(‘Subtract’);
subplot(2, 2, 3);
imshow(im3);
title(‘Multiply’);
subplot(2, 2, 4);
imshow(im4);
title(‘Divide’);

颜色反转 imcomplement

imcomplement(im);

2、直方图 Histograms

imhist(im),axis tight;

注意必须是灰度图,否则会报错

2.1直方图拉伸 Histogram Stretching

imadjust(im, [a, b], , gamma)

gamma不写默认值为1,[a, b]是要拉伸的范围,是拉伸后的范围,a、b、c、d均为0到1之间的double类型的数字

 

3月 202013
 

相关资源:

1、人脸识别的各种算法:http://www.face-rec.org/algorithms/

例:

Image-Based Face Recognition Algorithms

PCA|ICA|LDA|EP|EBGM|Kernel Methods|Trace Transform

AAM|3-D Morphable Model|3-D Face Recognition

Bayesian Framework|SVM|HMM|Boosting & Ensemble

Algorithms Comparisons

2、特征脸

Eigenfaces Group – Algorithmics

http://www.clear.rice.edu/elec301/Projects99/faces/algo.html

wiki

http://zh.wikipedia.org/wiki/%E7%89%B9%E5%BE%81%E8%84%B8

Seeing With OpenCV, Part 4: Face Recognition With Eigenface

http://www.cognotics.com/opencv/servo_2007_series/part_4/index.html

Seeing With OpenCV, Part 5: Implementing Eigenface

http://www.cognotics.com/opencv/servo_2007_series/part_5/index.html

3月 202013
 

先上代码

参考

http://www.opencv.org.cn/index.php/%E8%AF%BB%E8%A7%86%E9%A2%91%E6%96%87%E4%BB%B6%E5%92%8C%E8%BF%90%E5%8A%A8%E7%89%A9%E4%BD%93%E6%A3%80%E6%B5%8B

运动检测的原理就是,首先获取一张背景图,然后不断的读入每一帧动画,然后和背景图进行相减,得到的图即为可以检测运动的图像,然后还需要不断的更新背景图。

public class test {        
    public static void main(String args[]) throws Exception{ 
//声明IplImage指针
IplImage pFrame = null; 
IplImage pFrImg = null;
IplImage pBkImg = null;

CvMat pFrameMat = null;
CvMat pFrMat = null;
CvMat pBkMat = null;

CvCapture pCapture = null;

int nFrmNum = 0;

//创建窗口
cvNamedWindow("video", 1);
cvNamedWindow("background",1);
cvNamedWindow("foreground",1);
//使窗口有序排列
cvMoveWindow("video", 30, 0);
cvMoveWindow("background", 360, 0);
cvMoveWindow("foreground", 690, 0);
//打开视频文件
FrameGrabber grabber = FrameGrabber.createDefault(0);
	grabber.start();
	pFrame = grabber.grab();

//逐帧读取视频
while(pFrame!=null)
{
    nFrmNum++;

    //如果是第一帧,需要申请内存,并初始化
    if(nFrmNum == 1)
	{
	  pBkImg = cvCreateImage(cvSize(pFrame.width(), pFrame.height()),  IPL_DEPTH_8U,1);
	  pFrImg = cvCreateImage(cvSize(pFrame.width(), pFrame.height()),  IPL_DEPTH_8U,1);

	  pBkMat = cvCreateMat(pFrame.height(), pFrame.width(), CV_32FC1);
	  pFrMat = cvCreateMat(pFrame.height(), pFrame.width(), CV_32FC1);
	  pFrameMat = cvCreateMat(pFrame.height(), pFrame.width(), CV_32FC1);

	  //转化成单通道图像再处理
	  cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
	  cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);

	  cvConvert(pFrImg, pFrameMat);
	  cvConvert(pFrImg, pFrMat);
	  cvConvert(pFrImg, pBkMat);
	}
    else
	{
	  cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
	  cvConvert(pFrImg, pFrameMat);
	  //高斯滤波先,以平滑图像
	  //cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);

	  //当前帧跟背景图相减
	  cvAbsDiff(pFrameMat, pBkMat, pFrMat);

	  //二值化前景图
	  cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);

	  //进行形态学滤波,去掉噪音  
	  //cvErode(pFrImg, pFrImg, 0, 1);
	  //cvDilate(pFrImg, pFrImg, 0, 1);

	  //更新背景
	  cvRunningAvg(pFrameMat, pBkMat, 0.003, null);
	  //将背景转化为图像格式,用以显示
	  cvConvert(pBkMat, pBkImg);

	  //显示图像
	  cvShowImage("video", pFrame);
	  cvShowImage("background", pBkImg);
	  cvShowImage("foreground", pFrImg);

	  //如果有按键事件,则跳出循环
	  //此等待也为cvShowImage函数提供时间完成显示
	  //等待时间可以根据CPU速度调整
	  if( cvWaitKey(2) &gt;= 0 )
	    break;

	}
    try {
		pFrame = grabber.grab();
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
    }
		//销毁窗口
		cvDestroyWindow("video");
		cvDestroyWindow("background");
		cvDestroyWindow("foreground");

		//释放图像和矩阵
		cvReleaseImage(pFrImg);
		cvReleaseImage(pBkImg);

		cvReleaseMat(pFrameMat);
		cvReleaseMat(pFrMat);
		cvReleaseMat(pBkMat);

		cvReleaseCapture(pCapture);

    }
 }
3月 192013
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int Datatype;
int random(int i, int j)
{
    return i + rand() % (j-i+1);
}

int randomPartition(Datatype A[], int low, int high)
{
    int i = random(low,high);
    int temp;
    temp = A[high];
    A[high] = A[i];
    A[i] = temp;
    return  partition(A, low, high);
}
int partition(Datatype A[], int low, int high)
{
    int i=low,
        j=high;
    Datatype pivot = A[low];
    while(i < j)
    {
        while(i<j&&A[j] >= pivot) j--;
        if(i<j) A[i++] = A[j];
        while(i<j&&A[i] <= pivot) i++;
        if(i<j) A[j--] = A[i];
    }
    A[i] = pivot;
    return i;
}

void quicksort(Datatype A[], int low, int high)
{
    int divide;
    if(low<high)
    {
        divide = randomPartition(A,low,high);
        //divide = partition(A,low,high);
        quicksort(A, low, divide);
        quicksort(A, divide+1, high);
    }
}

int main()
{
    int i;
    Datatype A[10] ={2,4,6,1,7,3,9,1,90,23};
    quicksort(A, 0, sizeof(A)/sizeof(Datatype));
    for(i=0;i<(sizeof(A)/sizeof(Datatype));i++)
    {
        printf("%d ",A[i]);
    }
    printf("\n");
    return 0;
}

3月 162013
 

人脸识别,读入一张图片,检测人脸,当然也可以通过更换xml文件来检测眼睛,嘴巴等。
其中可以把检测图片这段代码注释,把中间的opencvframegrabber的注释去了,可以实时检测视频中的人脸,我的电脑貌似有点慢。
当然也可以用摄像头实时检测
参考
http://opencvlover.blogspot.com/2012/11/face-detection-in-javacv-using-haar.html

好吧这篇文章被墙了。

可能会提示CV_HAAR_DO_CANNY_PRUNING找不到
import这个即可。
import static com.googlecode.javacv.cpp.opencv_objdetect.*;
cvHaarDetectObjects参数调整:
调节程序中的缺省参数(scale_factor=1.1, min_neighbors=3, flags=0)用于对目标进行更精确同时也是耗时较长的进一步检测。为了能对视频图像进行更快的实时检测,参数设置通常是:scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING, min_size= (例如, 对于视频会议的图像区域)

public class test {  
	static CvMemStorage storage;
	static CvHaarClassifierCascade cascade;
	static String XML_FILE = "haarcascade_frontalface_default.xml";
        public static void main(String args[]) throws Exception{ 
	/* 视频人脸检测
	IplImage pFrame=null;
	OpenCVFrameGrabber grabber = new OpenCVFrameGrabber("infile2.wmv");
	grabber.start();
	//FrameGrabber grabber = FrameGrabber.createDefault(0);  //摄像头人脸检测
        //grabber.start();
        pFrame = grabber.grab();
        while( pFrame!=null )
        {
    	detect( pFrame );
        //cvReleaseImage( pFrame );
        pFrame = grabber.grab();
        if( cvWaitKey( 10 ) &gt;= 0 )
            break;
    }
   */
	IplImage img = cvLoadImage("xinsrc_1320805282048718186931.jpg");
	detect( img );

    }

    public static void detect(IplImage src){

		CvHaarClassifierCascade cascade = new 
				CvHaarClassifierCascade(cvLoad(XML_FILE));
		CvMemStorage storage = CvMemStorage.create();
		CvSeq sign = cvHaarDetectObjects(
				src,
				cascade,
				storage,
				1.2,
				2,
				CV_HAAR_DO_CANNY_PRUNING);

		cvClearMemStorage(storage);

		int total_Faces = sign.total();		
                if(total_Faces==0)
        	return;
		for(int i = 0; i &lt; total_Faces; i++){
			CvRect r = new CvRect(cvGetSeqElem(sign, i));
			cvRectangle (   src,
				        cvPoint(r.x(), r.y()),
					cvPoint(r.width() + r.x(), r.height() + r.y()),
					CvScalar.RED,
					2,
					CV_AA,
					0);

		}
		cvShowImage("Result", src);
		cvWaitKey( 0 );
	}
}
3月 162013
 

参考opencv示例

http://www.opencv.org.cn/index.php/%E5%9B%BE%E5%83%8F%E5%88%9B%E5%BB%BA%E3%80%81%E4%BF%9D%E5%AD%98%E5%92%8C%E5%A4%8D%E5%88%B6

public class test { 
public static void main(String args[]){ 
    IplImage image = cvLoadImage("lena.jpg");
    if(image==null)
    {
        System.err.print("Can not open file!\n");
        System.exit(1); 
    }

    IplImage pImg2 = cvCreateImage(cvGetSize(image),
    image.depth(),
    image.nChannels());
    cvCopy(image, pImg2, null);
    cvSaveImage("lena2.jpg", pImg2);//把图像写入文件 

    cvNamedWindow("Example",CV_WINDOW_AUTOSIZE); 
    //在窗口Example中显示图片
    cvShowImage("Example",image); 
    //暂停程序,等待用户触发一个按键
    cvWaitKey(0); 
    //释放图像所分配的内存 
    cvReleaseImage(image); 
    cvReleaseImage(pImg2); 
    //销毁窗口 
    cvDestroyWindow("Example"); 
    } 

}

首先保证当前工作目录下有图片文件,运行程序后
1、使用cvCopy(image, pImg2, null);来拷贝图片
2、使用cvSaveImage(“lena2.jpg”, pImg2);来保存图片
3、释放图片。
cvReleaseImage(image);
cvReleaseImage(pImg2);

3月 152013
 

这里的程序是参考别人的C语言程序移植过来的,没怎么学过java,玩CV顺便学下java吧

参考http://wenku.baidu.com/view/2b6fb9eb856a561252d36f4f.html

import static com.googlecode.javacv.cpp.opencv_core.*; 
import static com.googlecode.javacv.cpp.opencv_imgproc.*; 
import static com.googlecode.javacv.cpp.opencv_highgui.*;

public class test { 
   public static void main(String args[]){ 
      IplImage image = cvLoadImage("D:\\car.bmp"); 
      if (null == image)//如果读入失败,退出程序 
          System.exit(1); 
      //创建一个窗口,标题为Example 
      cvNamedWindow("Example",CV_WINDOW_AUTOSIZE); 
      //在窗口Example中显示图片
      cvShowImage("Example",image); 
      //暂停程序,等待用户触发一个按键
      cvWaitKey(0); 
      //释放图像所分配的内存 
      cvReleaseImage(image); 
      //销毁窗口 
      cvDestroyWindow("Example"); 
    } 
}
编译运行,这样就可以显示图片了,话说wordpress怎么上传图片呐- -
3月 152013
 

突然对Javacv感兴趣了,打算弄个人脸检测啥的,大企鹅已经有人脸登陆功能了。

1、下载OpenCV 2.4.4 http://sourceforge.net/projects/opencvlibrary/files/

2、安装,其实就是解压

3、设置环境变量

这里因为一开始也没有搭建成功所以设置了一堆。

…\opencv\build\x86\vc10\bin;

…\opencv\build;

…\opencv\build\x86\vc10\staticlib;

4、下载javacv-0.4-bin.zip

https://code.google.com/p/javacv/downloads/detail?name=javacv-0.4-bin.zip

这里我也把这个安装目录设置了环境变量,估计不需要,因为后面是直接拷贝到工程里的。

5、解压出一堆*.jar的文件

6、使用Eclipse新建工程

在新建的工程下新建一个文件目录libs/armeabi,建好之后把步骤5里面的jar文件拷贝到libs文件的根目录下

7、刷新项目,然后使用右键工程名->Build Path->Configure Build Path, 在里面Add JARS,把刚才拷贝过来的所有jar包都加入到项目中。

更详细参考

http://blog.csdn.net/haoba1987/article/details/8175390

会遇到的问题:

1、配置玩环境变量后,编译后提示找不到各种库*core,什么一堆库,估计还是环境没配置好,再加点或者试下重启什么的。
2、使用https://code.google.com/p/javacv/这里的示例程序,提示haarcascade_frontalface_alt.xml找不到,该文件在opencv\data\文件夹下面,还有其它的嘴巴、眼睛、body一堆。
3、现在关于javacv的参考太少了,API找不到,网上查了下,其API和python、C++什么的还是挺相似的。