视觉注意模型中的颜色特征划分

本文探讨了视觉注意模型中颜色特征的提取方法,基于亮度、色彩和方向特征。通过提取超过其他通道平均值的颜色通道,确定颜色特征。作者通过Python和C++实现这一过程,发现C++在运行时间上有优势,而Python在实现简洁性上更胜一筹。代码示例展示了如何使用numpy进行高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       昨天看了有关于视觉注意模型的算法的论文,说实话看懂的不多,所以就试着先试试一下图像的早期处理,视觉注意的图像早期处理分为三块,分别是亮度、色彩和方向特征的提取,其中亮度就是做灰度图,这一部分在前面的一片blog中已做了记录。现在要做的就是要进行颜色特征的提取,颜色特征提取论文中给出了相应的公式。

公式表明,任何一个颜色如果超过了其余两个通道的平均值,就说明这个颜色的通道占据主导位置,也就是颜色特征。这是我对于公式的一点个人理解,并不一定准确。比如我用经典的lena图像处理的时候,黄色和红色的特征图非常明显的能刻画出图像,但是蓝色只有头发部分可以显现出来,绿色没有任何显示,说明图像的绿色特征不明显。

这里是借鉴了人类视觉中存在着颜色拮抗的思路,所以要相应的提取出颜色特征。

      根据上述公式就可以得出每一张RGB图像的四个颜色特征图像。总体来说非常简单,只要是懂得操作图像像素基本都就可以。我分别使用了python和c++实现了这一功能,比较来看,在运行时间上,c++的优势还是异常明显的,但是要算算法实现难易程度,python则更加方便。

c++操作像素如果采用指针的方法遍历图像,将会非常快,但是缺点是不直观,尤其是在遍历多个图像的时候会显得很罗嗦。

       python遍历图像就差别比较大了,如果单纯的二重循环遍历,运行时间不理想,这只是算法其中一步,如果这一步需要时间过长,则会严重影响算法的工作,因此考虑用numpy中数组或者矩阵直接加减特性和过滤器的使用,速度会明显提升。这里要感谢网上的一位大神的指导。


代码如下:

python :暴力双重循环遍历

def getColorFeature(fileName = 'c.jpg'):
    img = cv2.imread(fileName)
    m = img.shape[0]
    n = img.shape[1]
    print img.shape
    channels = img.shape[2]
    b = np.zeros((m,n),img.dtype)
    g = np.zeros((m,n),img.dtype)
    r = np.zeros((m,n),img.dtype)
    y = np.zeros((m,n),img.dtype)
    for i in range(m):
        for j in range(n):
            B = np.float(img.item(i,j,0))
            G = np.float(img.item(i,j,1))
            R = np.float(img.item(i,j,2))
            if (R-(B+G)/2) <= 0:
                r[i,j] = 0
            else:
                r[i,j] = (R-(B+G)/2)
            if (B-(G+R)/2) <= 0:
                b[i,j] = 0
            else:
                b[i,j] = (B-(G+R)/2)
            if (G-(B+R)/2)<= 0:
                g[i,j] = 0
            else:
                g[i,j] = (G-(B+R)/2)
    cv2.imshow('origin',img)
    cv2.imshow('r',r)
    cv2.imshow('g',g)
    cv2.imshow('b',b)
    cv2.imshow('y',y)
    #cv2.waitKey()
    cv2.destroyAllWindows()

python:numpy数组加减与过滤器的使用

def color_feature(filename):
    img = cv2.imread(filename)
    float_img = img.astype(float)
    bg_average = (float_img[:, :, 0] + float_img[:, :, 1])/2
    rg_average = (float_img[:, :, 1] + float_img[:, :, 2])/2
    br_average = (float_img[:, :, 0] + float_img[:, :, 2])/2
    r = float_img[:, :,2] - bg_average
    r[ r< 0 ] = 0
    r = r.astype("uint8")
    g = float_img[:, :,1] - br_average
    g[ g < 0 ] = 0
    g = g.astype("uint8")
    b = float_img[:, :,0] - rg_average
    b[ b < 0] = 0
    b = b.astype("uint8")
    y = bg_average + np.abs(float_img[:, :,2]-float_img[:, :,1])/2 - float_img[:, :,0]
    y[y < 0] = 0
    y = y.astype("uint8")
    cv2.imshow('origin',img)
    cv2.imshow('r',r)
    cv2.imshow('g',g)
    cv2.imshow('b',b)
    cv2.imshow('y',y)
    cv2.waitKey()
    cv2.destroyAllWindows()

c++:基本是基于c语言的方法,指针移动遍历,同时接口也是c风格的。

// ColorFeature.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "cxcore.h"
#include "cv.h"
#include "highgui.h" 
#include "algorithm"
#include "time.h"
using namespace std;

clock_t start,finish;

int _tmain(int argc, _TCHAR* argv[])
{
	start = clock();
	IplImage *img =cvLoadImage("D://c.jpg");
	CvSize origin  = cvSize(img->width,img->height);
	//IplImage *gray = cvCreateImage(origin,8,1);
	IplImage *r = cvCreateImage(origin,8,1);
	IplImage *g = cvCreateImage(origin,8,1);
	IplImage *b = cvCreateImage(origin,8,1);
	for (int x = 0;x < img->height;x++){
		unsigned char* p1 = (unsigned char*) (img->imageData+x*img->widthStep);
		//unsigned char* pgray = (unsigned char*) (gray->imageData+x*gray->widthStep);
		unsigned char* pb = (unsigned char*) (b->imageData+x*b->widthStep);
		unsigned char* pg = (unsigned char*) (g->imageData+x*g->widthStep);
		unsigned char* pr = (unsigned char*) (r->imageData+x*r->widthStep);
	    for (int y = 0;y < img->width;y++){
			/*
			unsigned char vals[3];
			vals[0] = p1[3*y];
			vals[1] = p1[3*y+1];
			vals[2] = p1[3*y+2];
			*/
			//方法一:
			/*int temp = (vals[0]+vals[1]+vals[2])/3;
			pgray[y] = (unsigned char)(temp);*/
			//方法二:
			/*unsigned char temp1 = max(vals[0],vals[1]);
			int temp = max(temp1,vals[2]);
			pgray[y] = (unsigned char)(temp);*/

			//颜色特征提取算法
			unsigned char B = p1[3*y];
			unsigned char G = p1[3*y+1];
			unsigned char R = p1[3*y+2];
			int tempb = B-(R+G)/2;
			int tempg = G-(B+R)/2;
			int tempr = R-(G+B)/2;
			if (tempb > 0)
				pb[y] = unsigned char(tempb);
			else
				pb[y] = 0;
			if (tempg > 0)
				pg[y] = unsigned char(tempg);
			else
				pg[y] = 0;
			if (tempr > 0)
				pr[y] = unsigned char(tempr);
			else
				pr[y] = 0;
		}
	}
	finish = clock();
	printf("%fs\n",double(finish-start)/CLOCKS_PER_SEC);
	//cvNamedWindow("Gray");
	//cvShowImage("Gray",gray);
	cvNamedWindow("Origin");
	cvShowImage("Origin",img);
	cvNamedWindow("B");
	cvShowImage("B",b);
	cvNamedWindow("G");
	cvShowImage("G",g);
	cvNamedWindow("R");
	cvShowImage("R",r);
	cvWaitKey(0);
	//cvDestroyWindow("Gray");
	cvDestroyWindow("Origin");
	cvDestroyWindow("B");
	cvDestroyWindow("G");
	cvDestroyWindow("R");
	cvReleaseImage(&img);
	//cvReleaseImage(&gray);
	cvReleaseImage(&r);
	cvReleaseImage(&g);
	cvReleaseImage(&b);

	return 0;
}



如果我代码中有错误之处,或者对论文中的公式有理解的不对的地方,还请看到的大神路过指正!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值