利用cvKMeans2()实现图像聚类(位置+颜色)

///利用opencv提供的函数cvKMeans2()实现图像聚类

///////运行环境:VC6.0+opencv1.0

///////////////使用的时候,改变flag的初始值,即可实现对灰度图、彩色图基于色彩的聚类,以及根据位置和色彩对彩色图像聚类。

////////////////最后结果显示的时候请注意pResult 和pResult3

#include "cv.h"

#include "cxcore.h"

#include "highgui.h"

#include "cvaux.h"

#define nClusters 6

int main( )

{

IplImage* img = cvLoadImage("lena.jpg", 1);//

IplImage* pResult = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_8U, 1 );

IplImage* pResult3 = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_8U, 3 );

if(img==NULL)

return 0;

CvScalar color_tab[6];

color_tab[0] = CV_RGB(255,0,0);///给5中颜色分别赋值

color_tab[1] = CV_RGB(0,255,0);

color_tab[2] = CV_RGB(0,0,255);

color_tab[3] = CV_RGB(255,0,255);

color_tab[4] = CV_RGB(255,255,0);

color_tab[5] = CV_RGB(255,0,255);

CvMat* samples;

CvMat* clusters;

int flag=2;///0——灰度   1——彩色  2——位置+彩色

switch(flag)

{

case 0:///Gray

{

IplImage* pImg=cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_8U, 1 );

cvCvtColor(img, pImg, CV_BGR2GRAY);

assert(pImg != NULL&& pImg->nChannels== 1);

//创建样本矩阵,CV_32FC1代表位浮点通道(灰度图像)

samples = cvCreateMat((pImg->width)* (pImg->height),1, CV_32FC1);

//创建类别标记矩阵,CV_32SF1代表位整型通道

clusters = cvCreateMat((pImg->width)* (pImg->height),1, CV_32SC1);

//创建类别中心矩阵

//            CvMat*centers = cvCreateMat(nClusters, 1, CV_32FC1);

// 将原始图像转换到样本矩阵

{

int k = 0;

CvScalar s;

for(int i = 0; i < pImg->width; i++)

{

for(int j=0;j < pImg->height; j++)

{

s.val[0] = (float)cvGet2D(pImg, j, i).val[0];

cvSet2D(samples,k++, 0, s);

}

}

}

//开始聚类,迭代次,终止误差1.0

cvKMeans2(samples, nClusters,clusters, cvTermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS,100, 1.0));

// 无需排序直接输出时

int sortFlag = 0;

if (sortFlag == 0)

{

int k = 0;

int val = 0;

float step = 255 / ((float)nClusters - 1);

CvScalar s;

for(int i = 0; i < pImg->width; i++)

{

for(int j = 0;j < pImg->height; j++)

{

val = (int)clusters->data.i[k++];

s.val[0] = 255- val * step;//这个是将不同类别取不同的像素值

cvSet2D(pResult,j, i, s);  //将每个像素点赋值

}

}

}

printf( "Gray Image\n");

cvNamedWindow( "src", 1 );

cvShowImage( "src", pImg );

//释放图像内存资源

cvReleaseImage(&pImg);

break;

}//case0

case 1:///RGB

{

assert(img != NULL&& pResult != NULL);

assert(img->nChannels== 3 && pResult->nChannels == 1);

samples=cvCreateMat((img->width)*(img->height),1,CV_32FC3);//创建样本矩阵,CV_32FC3代表位浮点通道(彩色图像)

clusters=cvCreateMat((img->width)*(img->height),1,CV_32SC1);//创建类别标记矩阵,CV_32SF1代表位整型通道

int i,j,k=0;

for (i=0;i<img->width;i++)

{

for(j=0;j<img->height;j++)

{

CvScalar s;

//获取图像各个像素点的三通道值(RGB)

s.val[0]=(float)cvGet2D(img,j,i).val[0];

s.val[1]=(float)cvGet2D(img,j,i).val[1];

s.val[2]=(float)cvGet2D(img,j,i).val[2];

cvSet2D(samples,k++,0,s);//将像素点三通道的值按顺序排入样本矩阵

}

}

//cvTermCriteria(CV_TERMCRIT_ITER,100,1.0)

cvKMeans2(samples,nClusters,clusters,cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 1.0 ));//开始聚类,迭代次,终止误差1.0

k=0;

int val=0;

float step=255/(nClusters-1);

for (i=0;i<img->width;i++)

{

for(j=0;j<img->height;j++)

{

val=(int)clusters->data.i[k++];

CvScalar s;

s.val[0]=255-val*step;//这个是将不同类别取不同的像素值

cvSet2D(pResult3,j,i,color_tab[val]);        //将每个像素点赋值

}

}

printf( "RGB Image\n");

cvNamedWindow( "src", 1 );

cvShowImage( "src", img );

break;

}//case1

case 2:///Position+RGB

{

assert(img != NULL&& pResult != NULL);

assert(img->nChannels== 3 && pResult->nChannels == 1);

samples=cvCreateMat((img->width)*(img->height),5,CV_32FC1);//创建样本矩阵,CV_32FC3代表位浮点通道(彩色图像)

clusters=cvCreateMat((img->width)*(img->height),1,CV_32SC1);//创建类别标记矩阵,CV_32SF1代表位整型通道

int i=0,j,k=0;

int x,y;

float *data = samples->data.fl;

int matcol  = samples->cols;

int step1    = samples->step/sizeof(float);

for (x=0;x<img->width;x++)

{

for(y=0;y<img->height;y++)

{

//                    CvScalar s;

//获取图像各个像素点的三通道值(RGB)

//                    s.val[0]=(float)cvGet2D(img,y,x).val[0];

//                    s.val[1]=(float)cvGet2D(img,y,x).val[1];

//                    s.val[2]=(float)cvGet2D(img,y,x).val[2];

//                    cvSet2D(samples,k++,0,s);//将像素点三通道的值按顺序排入样本矩阵

data[i*matcol+0] = (float)x;

data[i*matcol+1] = (float)y;

data[i*matcol+2] = (float)cvGet2D(img,y,x).val[0];///cvGet2D(img,j,i).val[0];

data[i*matcol+3] = (float)cvGet2D(img,y,x).val[1];

data[i*matcol+4] = (float)cvGet2D(img,y,x).val[2];

i++;

}

}

//cvTermCriteria(CV_TERMCRIT_ITER,100,1.0)

cvKMeans2(samples,nClusters,clusters,cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 100, 1.0 ));//开始聚类,迭代次,终止误差1.0

k=0;

int val=0;

float step=255/(nClusters-1);

for (i=0;i<img->width;i++)

{

for(j=0;j<img->height;j++)

{

val=(int)clusters->data.i[k++];

CvScalar s;

s.val[0]=255-val*step;//这个是将不同类别取不同的像素值

cvSet2D(pResult,j,i,s);        //将每个像素点赋值

}

}

printf( "Positon+RGB Result\n");

cvNamedWindow( "src", 1 );

cvShowImage( "src", img );

break;

}//case2

}//switch

cvSaveImage("kmeansResult.jpg",pResult); //存储结果

cvNamedWindow( "result", 1 );cvMoveWindow("result",600,50);

cvShowImage( "result", pResult );

cvWaitKey(0);

//释放矩阵内存资源

cvReleaseMat(&samples);

cvReleaseMat(&clusters);

//释放图像内存资源

cvReleaseImage( &img);

cvReleaseImage( &pResult);

cvReleaseImage( &pResult3);

//释放窗口内存资源

cvDestroyWindow("src");

cvDestroyWindow("result");

return 1;

}

【致谢】http://blog.csdn.net/xidianzhimeng/article/details/10391603

利用cvKMeans2()实现图像聚类(位置+颜色)

时间: 2024-10-10 13:14:24

利用cvKMeans2()实现图像聚类(位置+颜色)的相关文章

Android 利用代码在屏幕中间位置显示ProgressDialog和ProgressBar

package cc.testprogressdialog; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.P

Python图像resize前后颜色不一致问题

今天帮师姐解决一个bug,测试了Python图像resize前后颜色不一致问题. 代码片段执行的功能:图像指定倍数超分辨率,输入为[0-1] float型数据,输出为格式不限的图像 bug:输入图像与输出图像颜色不一致 一.把产生bug的功能片段做分离测试: 1 import h5py 2 import numpy as np 3 import matplotlib.pyplot as plt 4 from PIL import Image 5 from scipy import misc 6

CKEditor去掉超链接和高级的方法,及上传和图像对调位置

项目中用不到超链接和高级,去掉的方法就是在config.js里加入 config.removeDialogTabs = 'image:advanced;image:Link'; 上传和图像对调位置:要修改这个目录下的plugins/image/dialogs/image.js 文件,文件代码虽然很多,但都会有解决的办法的.可以Ctrl+F搜一下Upload,这个就是上传图片的代码,整段复制到contents:[]里面去,记得是放在第一个位置,则就把上传图片就放到第一位置了.

利用LDA进行文本聚类(hadoop, mahout)

项目原理概述 利用sqoop将数据从MySQL导入到HDFS中,利用mahout的LDA的cvb实现对输入数据进行聚类,并将结果更新到数据库中.数据流向图如下 mahout算法分析 输入数据格式为<IntegerWritable, VectorWritable>的matrix矩阵,key为待聚类文本的数字编号,value为待聚类文本的单词向量Vector, Vector的index为单词在字典中的编号, value为TFIDF值. 算法相关参数详解(不包含hadoop运行参数)项目中所有参数设

利用matlab给图像加高斯噪声

I = imread('DSC_0034.JPG'); J = imnoise(I,'gaussian',0.20); figure, imshow(I), figure, imshow(J) 利用matlab给图像加高斯噪声

Dialog(九)——利用WindowManager在屏幕任意位置添加Dialog

MainActivity如下: package cn.testalertdialog; import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.WindowManager; import andro

为背景图像添加图像水印(位置随机)

1 <?php 2 /** 3 为背景图像添加水印(位置随机) 4 @param string $filename 需要添加水印的背景图片 5 @param string $water 水印图片 6 */ 7 function watermark($filename,$water){ 8 //获取背景图片的高和宽 9 list($b_w,$b_h) = getimagesize($filename); 10 //获取水印图片的高和宽 11 list($w_w,$w_h) = getimagesi

在代码插入图像的位置

在代码插入图像的位置将对如何显示图像产生影响.以下分别是在代码插入图像的三种位置由此也会产生不同效果. <!DOCTYPE html> <!-- To change this license header, choose License Headers in Project Properties. To change this template file, choose Tools | Templates and open the template in the editor. --&g

利用OpenCV检测图像中的长方形画布或纸张并提取图像内容

基于知乎上的一个答案.问题如下: 也就是在一张照片里,已知有个长方形的物体,但是经过了透视投影,已经不再是规则的长方形,那么如何提取这个图形里的内容呢?这是个很常见的场景,比如在博物馆里看到一幅很喜欢的画,用手机找了下来,可是回家一看歪歪斜斜,脑补原画内容又觉得不对,那么就需要算法辅助来从原图里提取原来的内容了.不妨把应用的场景分为以下: 纸张四角的坐标(图中红点)已知的情况 也就是上面的左图中4个红点是可以准确获取,比如手动标注,那么就简单了:用OpenCV的Perspective Trans