圖像特徵提取源碼
① 網上找到的SIFT特徵提取代碼,怎麼使用
這是源碼里針對找到圖像特徵點進行聚類的函數,運行到這里sift演算法已經結束了。可以試著吧調用kmeans演算法的部分注釋掉,搭陵只執行sift演算法然後打出來特徵點看一下效果。我也不明白弊枝叢在一張圖像上對特徵點聚類的意義何在。對多張圖像聚類租櫻還有意義。
② 對圖像進行邊緣特徵提取程序代碼
基於小波變換的多尺度燃睜大圖像邊緣檢測matlab源代皮豎碼(在Matlab7.0下早漏運行)
clear all;
load wbarb;
I = ind2gray(X,map);imshow(I);
I1 = imadjust(I,stretchlim(I),[0,1]);figure;imshow(I1);
[N,M] = size(I);
h = [0.125,0.375,0.375,0.125];
g = [0.5,-0.5];
delta = [1,0,0];
J = 3;
a(1:N,1:M,1,1:J+1) = 0;
dx(1:N,1:M,1,1:J+1) = 0;
dy(1:N,1:M,1,1:J+1) = 0;
d(1:N,1:M,1,1:J+1) = 0;
a(:,:,1,1) = conv2(h,h,I,'same');
dx(:,:,1,1) = conv2(delta,g,I,'same');
dy(:,:,1,1) = conv2(g,delta,I,'same');
x = dx(:,:,1,1);
y = dy(:,:,1,1);
d(:,:,1,1) = sqrt(x.^2+y.^2);
I1 = imadjust(d(:,:,1,1),stretchlim(d(:,:,1,1)),[0 1]);figure;imshow(I1);
lh = length(h);
lg = length(g);
for j = 1:J+1
lhj = 2^j*(lh-1)+1;
lgj = 2^j*(lg-1)+1;
hj(1:lhj)=0;
gj(1:lgj)=0;
for n = 1:lh
hj(2^j*(n-1)+1)=h(n);
end
for n = 1:lg
gj(2^j*(n-1)+1)=g(n);
end
a(:,:,1,j+1) = conv2(hj,hj,a(:,:,1,j),'same');
dx(:,:,1,j+1) = conv2(delta,gj,a(:,:,1,j),'same');
dy(:,:,1,j+1) = conv2(gj,delta,a(:,:,1,j),'same');
x = dx(:,:,1,j+1);
y = dy(:,:,1,j+1);
dj(:,:,1,j+1) = sqrt(x.^2+y.^2);
I1 = imadjust(dj(:,:,1,j+1),stretchlim(dj(:,:,1,j+1)),[0 1]);figure;imshow(I1);
End
③ 求人臉識別源代碼
基於Gabor特徵提取和人工智慧的人臉檢測系統源代碼Face Detection System
這是一個使用了Gabor特徵提取和人工智慧的人臉檢測系統源代碼關鍵內容
使用步驟:
1. 拷貝所有文件到MATLAB工作目錄下(確認已經安裝了圖像處理工具箱和人工智慧工具箱)
2. 找到"main.m"文件
3. 命令行中運行它
4. 點擊"Train Network",等待程序訓練好樣本
5. 點擊"Test on Photos",選擇一個.jpg圖片,識別。
6. 等待程序檢測出人臉區域
createffnn.m, drawrec.m, gabor.m, im2vec.m, imscan.m, loadimages.m, main.m, template1.png, template2.png, trainnet.m
④ 求matlab彩色圖片的顏色特徵提取演算法的代碼,和紋理特徵提取的代碼。傳統方法即可。
其實學數字圖像處理,關鍵的不是源代碼(和一般編程還是有區別的,這個是經驗之談,其實一般博導未必會編程,但是你和他說說你的方法,他一般都能切中要害),而是你能理解基於概念及適用場所。
基於顏色、紋理、形狀都屬於低層特徵,這些你理解就夠了,關鍵是對你的課題適合哪種方法來映射到高層語義上面,例如:識別物體輪廓,那可能形狀就比較適合等。
我之所以寫上面那段話,主要是我感覺你索取代碼也不說明具體要求,也就是方向不明確。
如今顏色特徵提取演算法有很多,諸如顏色直方圖、顏色矩、顏色集、顏色聚合向量、顏色相關圖等,既然你沒說,我就給個IEEE CSVT 2001的一篇關於顏色直方圖法的論文(源碼版權歸作者所有):
function colorhist = colorhist(rgb)
% CBIR_colorhist() --- color histogram calculation
% input: MxNx3 image data, in RGB
% output: 1x256 colorhistogram == (HxSxV = 16x4x4)
% as the MPEG-7 generic color histogram descriptor
% [Ref] Manjunath, B.S.; Ohm, J.-R.; Vasudevan, V.V.; Yamada, A., "Color and texture descriptors"
% IEEE Trans. CSVT, Volume: 11 Issue: 6 , Page(s): 703 -715, June 2001 (section III.B)
% check input
if size(rgb,3)~=3
error('3 components is needed for histogram');
end
% globals
H_BITS = 4; S_BITS = 2; V_BITS = 2;
%rgb2hsv可用rgb2hsi代替,見你以前的提問。
hsv = uint8(255*rgb2hsv(rgb));
imgsize = size(hsv);
% get rid of irrelevant boundaries
i0=round(0.05*imgsize(1)); i1=round(0.95*imgsize(1));
j0=round(0.05*imgsize(2)); j1=round(0.95*imgsize(2));
hsv = hsv(i0:i1, j0:j1, :);
% histogram
for i = 1 : 2^H_BITS
for j = 1 : 2^S_BITS
for k = 1 : 2^V_BITS
colorhist(i,j,k) = sum(sum( ...
bitshift(hsv(:,:,1),-(8-H_BITS))==i-1 &...
bitshift(hsv(:,:,2),-(8-S_BITS))==j-1 &...
bitshift(hsv(:,:,3),-(8-V_BITS))==k-1 ));
end
end
end
colorhist = reshape(colorhist, 1, 2^(H_BITS+S_BITS+V_BITS));
% normalize
colorhist = colorhist/sum(colorhist);
%基於紋理特徵提取灰度共生矩陣用於紋理判斷
% Calculates cooccurrence matrix
% for a given direction and distance
%
% out = cooccurrence (input, dir, dist, symmetric);
%
% INPUT:
% input: input matrix of any size
%
% dir: direction of evaluation
% "dir" value Angle
% 0 0
% 1 -45
% 2 -90
% 3 -135
% 4 -180
% 5 +135
% 6 +90
% 7 +45
%
% dist: distance between pixels
%
% symmetric: 1 for symmetric version
% 0 for non-symmetric version
%
% eg: out = cooccurrence (input, 0, 1, 1);
% Author: Baran Aydogan (15.07.2006)
% RGI, Tampere University of Technology
% [email protected]
function out = cooccurrence (input, dir, dist, symmetric);
input = round(input);
[r c] = size(input);
min_intensity = min(min(input));
max_intensity = max(max(input));
out = zeros(max_intensity-min_intensity+1);
if (dir == 0)
dir_x = 0; dir_y = 1;
end
if (dir == 1)
dir_x = 1; dir_y = 1;
end
if (dir == 2)
dir_x = 1; dir_y = 0;
end
if (dir == 3)
dir_x = 1; dir_y = -1;
end
if (dir == 4)
dir_x = 0; dir_y = -1;
end
if (dir == 5)
dir_x = -1; dir_y = -1;
end
if (dir == 6)
dir_x = -1; dir_y = 0;
end
if (dir == 7)
dir_x = -1; dir_y = 1;
end
dir_x = dir_x*dist;
dir_y = dir_y*dist;
out_ind_x = 0;
out_ind_y = 0;
for intensity1 = min_intensity:max_intensity
out_ind_x = out_ind_x + 1;
out_ind_y = 0;
[ind_x1 ind_y1] = find (input == intensity1);
ind_x1 = ind_x1 + dir_x;
ind_y1 = ind_y1 + dir_y;
for intensity2 = min_intensity:max_intensity
out_ind_y = out_ind_y + 1;
[ind_x2 ind_y2] = find (input == intensity2);
count = 0;
for i = 1:size(ind_x1,1)
for j = 1:size(ind_x2,1)
if ( (ind_x1(i) == ind_x2(j)) && (ind_y1(i) == ind_y2(j)) )
count = count + 1;
end
end
end
out(out_ind_x, out_ind_y) = count;
end
end
if (symmetric)
if (dir < 4)
dir = dir + 4;
else
dir = mod(dir,4);
end
out = out + cooccurrence (input, dir, dist, 0);
end
⑤ 我也求一份opencv下提取圖片sift特徵的項目源碼,急用,謝謝您了
#include "stdafx.h"
#include <opencv2/opencv.hpp>
double
compareSURFDescriptors( const float* d1, const float* d2, double best, int length )
{
double total_cost = 0;
assert( length % 4 == 0 );
for( int i = 0; i < length; i += 4 )
{
double t0 = d1[i ] - d2[i ];
double t1 = d1[i+1] - d2[i+1];
double t2 = d1[i+2] - d2[i+2];
double t3 = d1[i+3] - d2[i+3];
total_cost += t0*t0 + t1*t1 + t2*t2 + t3*t3;
if( total_cost > best )
break;
}
return total_cost;
}
int
naiveNearestNeighbor( const float* vec, int laplacian,
const CvSeq* model_keypoints,
const CvSeq* model_descriptors )
{
int length = (int)(model_descriptors->elem_size/sizeof(float));
int i, neighbor = -1;
double d, dist1 = 1e6, dist2 = 1e6;
CvSeqReader reader, kreader;
cvStartReadSeq( model_keypoints, &kreader, 0 );
cvStartReadSeq( model_descriptors, &reader, 0 );
for( i = 0; i < model_descriptors->total; i++ )
{
const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;
const float* mvec = (const float*)reader.ptr;
CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
if( laplacian != kp->laplacian )
continue;
d = compareSURFDescriptors( vec, mvec, dist2, length );
if( d < dist1 )
{
dist2 = dist1;
dist1 = d;
neighbor = i;
}
else if ( d < dist2 )
dist2 = d;
}
if ( dist1 < 0.6*dist2 )
return neighbor;
return -1;
}
void
findPairs( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors,
const CvSeq* imageKeypoints, const CvSeq* imageDescriptors, vector<int>& ptpairs )
{
int i;
CvSeqReader reader, kreader;
cvStartReadSeq( objectKeypoints, &kreader );
cvStartReadSeq( objectDescriptors, &reader );
ptpairs.clear();
for( i = 0; i < objectDescriptors->total; i++ )
{
const CvSURFPoint* kp = (const CvSURFPoint*)kreader.ptr;
const float* descriptor = (const float*)reader.ptr;
CV_NEXT_SEQ_ELEM( kreader.seq->elem_size, kreader );
CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
int nearest_neighbor = naiveNearestNeighbor( descriptor, kp->laplacian, imageKeypoints, imageDescriptors );
if( nearest_neighbor >= 0 )
{
ptpairs.push_back(i);
ptpairs.push_back(nearest_neighbor);
}
}
}
void
flannFindPairs( const CvSeq*, const CvSeq* objectDescriptors,
const CvSeq*, const CvSeq* imageDescriptors, vector<int>& ptpairs )
{
int length = (int)(objectDescriptors->elem_size/sizeof(float));
cv::Mat m_object(objectDescriptors->total, length, CV_32F);
cv::Mat m_image(imageDescriptors->total, length, CV_32F);
// descriptors
CvSeqReader obj_reader;
float* obj_ptr = m_object.ptr<float>(0);
cvStartReadSeq( objectDescriptors, &obj_reader );
for(int i = 0; i < objectDescriptors->total; i++ )
{
const float* descriptor = (const float*)obj_reader.ptr;
CV_NEXT_SEQ_ELEM( obj_reader.seq->elem_size, obj_reader );
memcpy(obj_ptr, descriptor, length*sizeof(float));
obj_ptr += length;
}
CvSeqReader img_reader;
float* img_ptr = m_image.ptr<float>(0);
cvStartReadSeq( imageDescriptors, &img_reader );
for(int i = 0; i < imageDescriptors->total; i++ )
{
const float* descriptor = (const float*)img_reader.ptr;
CV_NEXT_SEQ_ELEM( img_reader.seq->elem_size, img_reader );
memcpy(img_ptr, descriptor, length*sizeof(float));
img_ptr += length;
}
// find nearest neighbors using FLANN
cv::Mat m_indices(objectDescriptors->total, 2, CV_32S);
cv::Mat m_dists(objectDescriptors->total, 2, CV_32F);
cv::flann::Index flann_index(m_image, cv::flann::KDTreeIndexParams(4)); // using 4 randomized kdtrees
flann_index.knnSearch(m_object, m_indices, m_dists, 2, cv::flann::SearchParams(64) ); // maximum number of leafs checked
int* indices_ptr = m_indices.ptr<int>(0);
float* dists_ptr = m_dists.ptr<float>(0);
for (int i=0;i<m_indices.rows;++i) {
if (dists_ptr[2*i]<0.6*dists_ptr[2*i+1]) {
ptpairs.push_back(i);
ptpairs.push_back(indices_ptr[2*i]);
}
}
}
/* a rough implementation for object location */
int
locatePlanarObject( const CvSeq* objectKeypoints, const CvSeq* objectDescriptors,
const CvSeq* imageKeypoints, const CvSeq* imageDescriptors,
const CvPoint src_corners[4], CvPoint dst_corners[4] )
{
double h[9];
CvMat _h = cvMat(3, 3, CV_64F, h);
vector<int> ptpairs;
vector<CvPoint2D32f> pt1, pt2;
CvMat _pt1, _pt2;
int i, n;
#ifdef USE_FLANN
flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
#else
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
#endif
n = (int)(ptpairs.size()/2);
if( n < 4 )
return 0;
pt1.resize(n);
pt2.resize(n);
for( i = 0; i < n; i++ )
{
pt1[i] = ((CvSURFPoint*)cvGetSeqElem(objectKeypoints,ptpairs[i*2]))->pt;
pt2[i] = ((CvSURFPoint*)cvGetSeqElem(imageKeypoints,ptpairs[i*2+1]))->pt;
}
_pt1 = cvMat(1, n, CV_32FC2, &pt1[0] );
_pt2 = cvMat(1, n, CV_32FC2, &pt2[0] );
if( !cvFindHomography( &_pt1, &_pt2, &_h, CV_RANSAC, 5 ))
return 0;
for( i = 0; i < 4; i++ )
{
double x = src_corners[i].x, y = src_corners[i].y;
double Z = 1./(h[6]*x + h[7]*y + h[8]);
double X = (h[0]*x + h[1]*y + h[2])*Z;
double Y = (h[3]*x + h[4]*y + h[5])*Z;
dst_corners[i] = cvPoint(cvRound(X), cvRound(Y));
}
return 1;
}
int main(int argc, char** argv)
{
const char* object_filename = argc == 3 ? argv[1] : "box.png";
const char* scene_filename = argc == 3 ? argv[2] : "box_in_scene.png";
IplImage* object = cvLoadImage( object_filename, CV_LOAD_IMAGE_GRAYSCALE );
IplImage* image = cvLoadImage( scene_filename, CV_LOAD_IMAGE_GRAYSCALE );
if( !object || !image )
{
fprintf( stderr, "Can not load %s and/or %s\n",
object_filename, scene_filename );
exit(-1);
}
CvMemStorage* storage = cvCreateMemStorage(0);
cvNamedWindow("Object", 1);
cvNamedWindow("Object Correspond", 1);
static CvScalar colors[] =
{
{{0,0,255}},
{{0,128,255}},
{{0,255,255}},
{{0,255,0}},
{{255,128,0}},
{{255,255,0}},
{{255,0,0}},
{{255,0,255}},
{{255,255,255}}
};
IplImage* object_color = cvCreateImage(cvGetSize(object), 8, 3);
cvCvtColor( object, object_color, CV_GRAY2BGR );
CvSeq* objectKeypoints = 0, *objectDescriptors = 0;
CvSeq* imageKeypoints = 0, *imageDescriptors = 0;
int i;
CvSURFParams params = cvSURFParams(500, 1);
double tt = (double)cvGetTickCount();
cvExtractSURF( object, 0, &objectKeypoints, &objectDescriptors, storage, params );
printf("Object Descriptors: %d\n", objectDescriptors->total);
cvExtractSURF( image, 0, &imageKeypoints, &imageDescriptors, storage, params );
printf("Image Descriptors: %d\n", imageDescriptors->total);
tt = (double)cvGetTickCount() - tt;
printf( "Extraction time = %gms\n", tt/(cvGetTickFrequency()*1000.));
CvPoint src_corners[4] = {{0,0}, {object->width,0}, {object->width, object->height}, {0, object->height}};
CvPoint dst_corners[4];
IplImage* correspond = cvCreateImage( cvSize(image->width, object->height+image->height), 8, 1 );
cvSetImageROI( correspond, cvRect( 0, 0, object->width, object->height ) );
cvCopy( object, correspond );
cvSetImageROI( correspond, cvRect( 0, object->height, correspond->width, correspond->height ) );
cvCopy( image, correspond );
cvResetImageROI( correspond );
#ifdef USE_FLANN
printf("Using approximate nearest neighbor search\n");
#endif
if( locatePlanarObject( objectKeypoints, objectDescriptors, imageKeypoints,
imageDescriptors, src_corners, dst_corners ))
{
for( i = 0; i < 4; i++ )
{
CvPoint r1 = dst_corners[i%4];
CvPoint r2 = dst_corners[(i+1)%4];
cvLine( correspond, cvPoint(r1.x, r1.y+object->height ),
cvPoint(r2.x, r2.y+object->height ), colors[8] );
}
}
vector<int> ptpairs;
#ifdef USE_FLANN
flannFindPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
#else
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs );
#endif
for( i = 0; i < (int)ptpairs.size(); i += 2 )
{
CvSURFPoint* r1 = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, ptpairs[i] );
CvSURFPoint* r2 = (CvSURFPoint*)cvGetSeqElem( imageKeypoints, ptpairs[i+1] );
cvLine( correspond, cvPointFrom32f(r1->pt),
cvPoint(cvRound(r2->pt.x), cvRound(r2->pt.y+object->height)), colors[8] );
}
cvShowImage( "Object Correspond", correspond );
for( i = 0; i < objectKeypoints->total; i++ )
{
CvSURFPoint* r = (CvSURFPoint*)cvGetSeqElem( objectKeypoints, i );
CvPoint center;
int radius;
center.x = cvRound(r->pt.x);
center.y = cvRound(r->pt.y);
radius = cvRound(r->size*1.2/9.*2);
cvCircle( object_color, center, radius, colors[0], 1, 8, 0 );
}
cvShowImage( "Object", object_color );
cvWaitKey(0);
cvDestroyWindow("Object");
cvDestroyWindow("Object Correspond");
return 0;
}
⑥ matlab特徵提取相關代碼求解答
提取網站的部分源代碼 是不需要軟體的 Internet Explorer
本身就支持JSP,ASP等網頁編輯的代碼.
操作方法: 在頁面宏扮空白處單擊右鍵 選擇 查看源文件(V)
(其中有一些獨立的加密文基絕肢件是無權查搏世看的,
即便是你使用第三方軟體,被加密的文件也無法復制或篡改)
⑦ 求基於matlab指紋掃描圖像處理的源代碼
clear all,close all,clc % 清理工作空間,關閉運行窗口,清理命令窗口
I=imread('Empreinte.bmp'); % 讀入圖像
imshow(I) % 顯示圖像
set(gcf,'position',[1 1 600 600]); % 得到圖形窗口句柄,設置圖形窗口位置
J=I(:,:,1)>160; % 設定閾值為160,進行黑白化處理
imshow(J) % 顯示處理後的圖像
set(gcf,'position',[1 1 600 600]); % 得到圖形窗口句柄,設置圖形窗口位置
K=bwmorph(~J,'thin','inf'); % 數學形態學運算,圖像細化,~符號代表黑白反色
imshow(~K) % 顯示處理後的圖像,~符號代表黑白反色
set(gcf,'position',[1 1 600 600]); % 得到圖形窗口句柄,設置圖形窗口位置
function y=minutie(x)
i=ceil(size(x)/2);
if x(i,i)==0;
y=0;
else
y=sum(x(:)) - 1;
end
fun=@minutie; % 得到函數句柄
L = nlfilter(K,[3 3],fun); % 濾波處理
LTerm=(L==1); % 選擇端點
imshow(LTerm) % 顯示白色點
LTermLab=bwlabel(LTerm); % 端點標識
propTerm=regionprops(LTermLab,'Centroid'); % 端點區域分析,尋找端點區域中心
CentroidTerm=round(cat(1,propTerm(:).Centroid)); % 端點圓整為整數
imshow(~K) % 顯示隆線細化圖像
set(gcf,'position',[1 1 600 600]); % 得到當前圖形窗口句柄,設置位置
hold on % 在前面的圖形窗口繼續繪制圖像
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro') % 繪制隆線端點標識,紅色圓圈
LBif=(L==3); % 選擇分叉點
LBifLab=bwlabel(LBif); % 分叉點標識
propBif=regionprops(LBifLab,'Centroid','Image'); % 區域分析,尋找區域中心
CentroidBif=round(cat(1,propBif(:).Centroid)); % 分叉點圓整為整數
plot(CentroidBif(:,1),CentroidBif(:,2),'go') % 繪制隆線分叉點標識,綠色圓圈
D=6;
Distance=DistEuclidian(CentroidBif,CentroidTerm); % 求端點和分叉點的距離
SpuriousMinutae=Distance<D; % 滿足距離小於D的點
[i,j]=find(SpuriousMinutae); % 查找對應像素點
CentroidBif(i,:)=[]; % 去除該分叉點
CentroidTerm(j,:)=[]; % 去除該端點
Distance=DistEuclidian(CentroidBif); % 求兩個分叉點的距離
SpuriousMinutae=Distance<D; % 滿足距離小於D的點
[i,j]=find(SpuriousMinutae); % 查找對應像素點
CentroidBif(i,:)=[]; % 去除該分叉點
Distance=DistEuclidian(CentroidTerm); % 求兩個端點的距離
SpuriousMinutae=Distance<D; % 滿足距離小於D的點
[i,j]=find(SpuriousMinutae); % 查找對應像素點
CentroidTerm(i,:)=[]; % 去除該端點
hold off % 結束在前面的圖形窗口繪圖
imshow(~K) % 顯示細化圖
hold on % 繼續在前面的圖形窗口繪圖
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro') % 繪制隆線端點標識,紅色圓圈
plot(CentroidBif(:,1),CentroidBif(:,2),'go') % 繪制隆線分叉點標識,綠色圓圈
hold off % 結束在前面的圖形窗口繪圖
Kopen=imclose(K,strel('square',7)); % 閉合運算
KopenClean= imfill(Kopen,'holes'); % 填充圖像中的孔洞
KopenClean=bwareaopen(KopenClean,5); % 開運算
imshow(KopenClean) % 顯示處理結果
KopenClean([1 end],:)=0; % 賦值語句
KopenClean(:,[1 end])=0; % 賦值語句
ROI=imerode(KopenClean,strel('disk',10)); % 腐蝕運算
imshow(ROI) % 顯示處理結果
imshow(I) % 顯示原始圖像
hold on % 繼續在前面的圖形窗口繪圖
imshow(ROI) % 顯示感興趣區域
alpha(0.5) % 設置透明度
hold on % 繼續在前面的圖形窗口繪圖
plot(CentroidTerm(:,1),CentroidTerm(:,2),'ro') % 繪制端點標識,紅色圓圈
plot(CentroidBif(:,1),CentroidBif(:,2),'go') % 繪制分叉點標識,綠色圓圈
hold off % 結束在前面的圖形窗口繪圖
[m,n]=size(I(:,:,1)); % 求圖像尺寸
indTerm=sub2ind([m,n]; % 從下標得到單精度索引
CentroidTerm(:,1),CentroidTerm(:,2)); % 端點
Z=zeros(m,n); % 全零矩陣
Z(indTerm)=1;
ZTerm=Z.*ROI';
[CentroidTermX,CentroidTermY]=find(ZTerm);
indBif=sub2ind([m,n],CentroidBif(:,1),CentroidBif(:,2)); % 從下標得到單精度索引
Z=zeros(m,n);
Z(indBif)=1;
ZBif=Z.*ROI';
[CentroidBifX,CentroidBifY]=find(ZBif);
imshow(I) % 顯示原始圖像
hold on % 繼續繪圖
plot(CentroidTermX,CentroidTermY,'ro','linewidth',2) % 紅色圓圈
plot(CentroidBifX,CentroidBifY,'go','linewidth',2) % 綠色圓圈
Table=[3*pi/4 2*pi/3 pi/2 pi/3 pi/4 % 角度查找表
5*pi/6 0 0 0 pi/6
pi 0 0 0 0
-5*pi/6 0 0 0 -pi/6
-3*pi/4 -2*pi/3 -pi/2 -pi/3 -pi/4];
for ind=1:length(CentroidTermX)
Klocal=K(CentroidTermY(ind)-2:CentroidTermY(ind)+2, ...
CentroidTermX(ind)-2:CentroidTermX(ind)+2);
Klocal(2:end-1,2:end-1)=0;
[i,j]=find(Klocal);
OrientationTerm(ind,1)=Table(i,j);
end
dxTerm=sin(OrientationTerm)*5;
dyTerm=cos(OrientationTerm)*5;
figure % 新建窗口
imshow(K) % 顯示黑白圖
set(gcf,'position',[1 1 600 600]); % 設置圖像窗口屬性
hold on % 繼續繪圖
plot(CentroidTermX,CentroidTermY,'ro','linewidth',2) % 紅色圓圈
plot([CentroidTermX CentroidTermX+dyTerm]',... % 紅色短線
[CentroidTermY CentroidTermY-dxTerm]','r','linewidth',2)
for ind=1:length(CentroidBifX)
Klocal=K(CentroidBifY(ind)-2:CentroidBifY(ind)+2, ...
CentroidBifX(ind)-2:CentroidBifX(ind)+2);
Klocal(2:end-1,2:end-1)=0;
[i,j]=find(Klocal);
if length(i)~=3
CentroidBifY(ind)=NaN;
CentroidBifX(ind)=NaN;
OrientationBif(ind)=NaN;
else
for k=1:3
OrientationBif(ind,k)=Table(i(k),j(k));
dxBif(ind,k)=sin(OrientationBif(ind,k))*5;
dyBif(ind,k)=cos(OrientationBif(ind,k))*5;
end
end
end
plot(CentroidBifX,CentroidBifY,'go','linewidth',2) % 綠色圓圈
OrientationLinesX=[CentroidBifX ...
CentroidBifX+dyBif(:,1);CentroidBifX ...
CentroidBifX+dyBif(:,2);CentroidBifX CentroidBifX+dyBif(:,3)]';
OrientationLinesY=[CentroidBifY
CentroidBifY-dxBif(:,1);CentroidBifY ...
CentroidBifY-dxBif(:,2);CentroidBifY CentroidBifY-dxBif(:,3)]';
plot(OrientationLinesX,OrientationLinesY,'g','linewidth',2) % 綠色短線
MinutiaTerm=[CentroidTermX,CentroidTermY,OrientationTerm];
MinutiaBif=[CentroidBifX,CentroidBifY,OrientationBif];
saveMinutia('John Doe',MinutiaTerm,MinutiaBif); % saveMinutia函數見附件程序
⑧ OpenCV3.0.0中關於ORB演算法提取特徵點的程序怎麼寫還有ORB演算法的源碼位置在哪裡
先新建工程,控制台程序,然後把代碼復制進去
接著添加庫函數,然後調試運行,看看出現什麼錯誤再接著更改。
對了,還要將你要匹配的圖像文件放到工程文件的目錄下。
⑨ 紋理特徵提取方法:LBP, 灰度共生矩陣
搬運自本人 CSDN 博客: 《紋理特徵提取方法:LBP, 灰度共生矩陣》
註:本文中大量行內 Latex 公式在中不支持,如果想要仔細參閱,請移步上面的 CSDN 博客鏈接。
在前面的博文 《圖像紋理特徵總體簡述》 中,筆者總結了圖像紋理特徵及其分類。在這里筆者對其中兩種演算法介紹並總結。
參考網址:
《紋理特徵提取》
《【紋理特徵】LBP 》
《灰度共生矩陣(GLCM)理解》
《灰度共生矩陣的理解》
《圖像的紋理特徵之灰度共生矩陣 》
參考論文:
《基於灰度共生矩陣提取紋理特徵圖像的研究》——馮建輝
《灰度共生矩陣紋理特徵提取的Matlab實現》——焦蓬蓬
LBP方法(Local binary patterns, 局部二值模式)是一種用來描述圖像局部紋理特徵的運算元;它的作用是進行特徵提取,提取圖像的局部紋理特徵。
LBP是一個計算機視覺中用於圖像特徵分類的一個方法,用於紋理特徵提取。後來LBP方法與HOG特徵分類器與其他機器學習演算法聯合使用。
LBP演算法的核心思想,是以某個像素點為中心,與其鄰域像素點共同計算。關於鄰域像素點的選擇方法,其實並不唯一:
這里選擇環形鄰域的方法進行說明:
窗口中心的像素點作為中心,該像素點的像素值作為閾值。然後將周圍8個像素點的灰度值與該閾值進行比較,若周圍某像素值大於中心像素值,則該像素點位置被標記為1;反之,該像素點標記為0。
如此這樣,該窗口的8個點可以產生8位的無符號數,這樣就得到了該窗口的LBP值,該值反應了該窗口的紋理信息。如下圖所示:
圖中,中心像素點的像素值作為閾值,其值v = 3;周圍鄰域8個像素值中,橘塌如有3個比閾值小的像素點置0,5個比閾值大的像素點置1。
LBP演算法的計算公式如下:
$$ LBP_{P, R}(x_{c},y_{c}) = sum_{p=0}^{P-1}s(g_{p} - g_{c})2^p, s(x)=left{egin{matrix}1 : x geq 0 0 : x leq 0 end{matrix} ight. $$
LBP紋理特徵向量,一般以圖像分塊LBP直方圖表示。具體步驟如下:
得到了整幅圖像的LBP紋理特徵後,便可以利用SVM或者其他機器學習演算法進行分類了。
這兩天筆者將會對源碼進行測試封裝,以後會上傳到我的GitHub網站上。
灰度共生矩陣法(GLCM, Gray-level co-occurrence matrix),就是通過計算灰度圖像得到它的共生矩陣,然後透過計算該共生矩陣得到矩陣的部分特徵值,來分別代表圖像的某些紋理特徵(紋理的定義仍是難點)。灰度共生圓啟矩陣能反映圖像灰度關於<font color = red> 方向、相鄰間隔、變化幅度等 </font>綜合信息,它是分析圖像的局部模式和它們排列規則的基礎。
對於灰度共生矩陣的理解,需要明確幾個概念:方向,偏移量和灰度共生矩陣的階數。
計算紋理特徵第一步,就是將多通道的圖像(一般指RGB圖像)轉換為灰度圖像,分別提取出多個通道的灰度圖像。
紋理特徵是一種結構特徵,使用不同通道圖像得到的紋理特徵都是一樣的,所以可以任意選擇其一。
一般在一幅圖像中的灰度級有256級,從0--255。但在計算灰度共生矩陣時我們並不需要256個灰度級,且計算量實在太大,所以一般分為8個灰度級或16個灰度級。
而且當分成8個灰度級時,如果直接將像素點的灰度值除以32取整,會引起影像清晰度降低,所以進行灰度級壓縮時,首先我們會將圖片進行直方圖均衡化處理,增加灰度值的動態范圍,這樣就增加了影像的整體對比效果。
註:筆者後文中的例子中,為了簡要說明,所以灰衫肢度等級簡單設置為4。
計算特徵值前,先選擇計算過程中的一些參數:
下面分部且適當的使用一些例子說明計算過程:
為了達到簡單說明計算紋理特徵值的目的,筆者此處做簡要的假設:灰度被分為4階,灰度階從0--3;窗口大小為6 × 6;
窗口A的灰度矩陣A如下:
窗口B的灰度矩陣B如下:
此處以左上角元素為坐標原點,原點記為(1, 1);以此為基礎舉例,第四行第二列的點記為(4, 2);
情景1:d = 1,求0°方向矩陣A的共生矩陣:
則按照0°方向(即水平方向 從左向右,從右向左兩個方向 ),統計矩陣值(1, 2),則如下圖所示:
$$
P_{A}(d=1, heta =0^o)=egin{vmatrix}
0 & 8 & 0 & 7
8 & 0 & 8 & 0
0 & 8 & 0 & 7
7 & 0 & 7 & 0
end{vmatrix}
$$
情景2:d = 1,求45°方向矩陣A的共生矩陣:
按照情景1,同理可得此時的統計矩陣結果如下:
$$
P_{A}(d=1, heta =45^o)=egin{vmatrix}
12 & 0 & 0 & 0
0 & 14 & 0 & 0
0 & 0 & 12 & 0
0 & 0 & 0 & 12
end{vmatrix}
$$
情景3:d = 1,求0°與45°方向矩陣B的共生矩陣:
與前面同理,可以得到矩陣B的統計及矩陣結果如下:
$$
P_{B}(d=1, heta =0^o)=egin{vmatrix}
24 & 4 & 0 & 0
4 & 8 & 0 & 0
0 & 0 & 12 & 2
0 & 0 & 2 & 4
end{vmatrix}
$$
$$
P_{B}(d=1, heta =45^o)=egin{vmatrix}
18 & 3 & 3 & 0
3 & 6 & 1 & 1
3 & 1 & 6 & 1
0 & 1 & 1 & 2
end{vmatrix}
$$
矩陣A, B的其餘90°、135°矩陣與上面同理,所以筆者偷懶略去。
這樣,我們就已經計算得到了單個窗口的灰度共生矩陣的各個方向的矩陣,下面就要用剛才算出的矩陣計算灰度共生矩陣特徵值。
用P表示灰度共生矩陣的歸一化頻率矩陣,其中i, j表示按照某方向同時出現於兩個像素的某兩個級別的灰度值,所以P(i, j)表示滿足這種情況的兩個像素出現的概率。
以上述情景2中的矩陣為例:
原矩陣為:
$$
P(d=1, heta =45^o)=egin{vmatrix}
12 & 0 & 0 & 0
0 & 14 & 0 & 0
0 & 0 & 12 & 0
0 & 0 & 0 & 12
end{vmatrix}
$$
歸一化後,矩陣形式變為:
$$
P(d=1, heta =45^o)=egin{vmatrix}
12/50 & 0 & 0 & 0
0 & 14/50 & 0 & 0
0 & 0 & 12/50 & 0
0 & 0 & 0 & 12/50
end{vmatrix}
$$
灰度共生矩陣理論的前輩Haralick等人用灰度共生矩陣提出了14中特徵值,但由於灰度共生矩陣的計算量很大,所以為了簡便,我們一般採用四個最常用的特徵來提取圖像的紋理特徵:<font color=red> 能量、對比度、相關度、熵 </font>。
$ ASM = sum_{i} sum_{j}P(i, j)^2 $
能量是灰度共生矩陣各元素的平方和,又被稱角二階距。它是圖像紋理灰度變化均一的度量,反映了圖像灰度分布均勻程度和紋理粗細程度。
$ CON = sum_{i} sum_{j} (i-j)^2 P(i,j) $
對比度是灰度共生矩陣主對角線附近的慣性矩,它體現矩陣的值如何分布,反映了圖像的清晰度和紋理溝紋的深淺。
$ CORRLN = [sum_{i} sum_{j}((ij)P(i,j)) - mu_{x} mu_{y}]/ sigma_{x} sigma_{y} $
相關度體現了空間灰度共生矩陣元素在行或列方向上的相似程度,反映了圖像局部灰度相關性。
$ ENT = - sum_{i} sum_{j} P(i,j) log P(i,j) $
熵體現了圖像紋理的隨機性。若共生矩陣中所有值都相等,取得最大值;若共生矩陣中的值不均勻,則其值會變得很小。
求出該灰度共生矩陣各個方向的特徵值後,再對這些特徵值進行均值和方差的計算,這樣處理就消除了方向分量對紋理特徵的影響。
一個滑動窗口計算結束後,該窗口就可以移動一個像素點,形成另一個小窗口圖像,重復進行上一步的計算,生成新窗口圖像的共生矩陣和紋理特徵值;
以此類推,滑動窗口遍歷完所有的圖像像素點後,整個圖像就形成了一個由紋理特徵值構成的一個紋理特徵值矩陣。
之後,就可以將這個紋理特徵值矩陣轉換成紋理特徵圖像。
筆者已經對源碼進行測試了封裝,並上傳到了筆者的GitHub網站上。
GitHub: https://github.com/upcAutoLang/GLCM-OpenCV
⑩ 常用的十大python圖像處理工具
原文標題:10 Python image manipulation tools.
作者 | Parul Pandey
翻譯 | 安其羅喬爾、JimmyHua
今天,在我們的世界裡充滿了數據,圖像成為構成這些數據的重要組成部分。但無論是用於何種用途,這些圖像都需要進行處理。圖像處理就是分析和處理數字圖像的過程,主要旨在提高其質量或從中提取一些信息,然後可以將其用於某種用途。
圖像處理中的常見任務包括顯示圖像,基本操作如裁剪、翻轉、旋轉等,圖像分割,分類和特徵提取,圖像恢復和圖像識別。Python成為這種圖像處理任務是一個恰當選擇,這是因為它作為一種科學編程語言正在日益普及,並且在其生態系統中免費提供許多最先進的圖像處理工具供大家使用。
讓我們看一下可以用於圖像處理任務中的常用 Python 庫有哪些吧。
1.scikit-image
scikit-image是一個開源的Python包,適用於numpy數組。它實現了用於研究,教育和工業應用的演算法和實用工具。即使是那些剛接觸Python生態系統的人,它也是一個相當簡單直接的庫。此代碼是由活躍的志願者社區編寫的,具有高質量和同行評審的性質。
資源
文檔里記錄了豐富的例子和實際用例,閱讀下面的文檔:
http://scikit-image.org/docs/stable/user_guide.html
用法
該包作為skimage導入,大多數功能都在子模塊中找的到。下面列舉一些skimage的例子:
圖像過濾
使用match_template函數進行模板匹配
你可以通過此處查看圖庫找到更多示例。
2. Numpy
Numpy是Python編程的核心庫之一,並為數組提供支持。圖像本質上是包含數據點像素的標准Numpy數組。因此,我們可以通過使用基本的NumPy操作,例如切片、掩膜和花式索引,來修改圖像的像素值。可以使用skimage載入圖像並使用matplotlib顯示圖像。
資源
Numpy的官方文檔頁面提供了完整的資源和文檔列表:
http://www.numpy.org/
用法
使用Numpy來掩膜圖像.
3.Scipy
scipy是Python的另一個類似Numpy的核心科學模塊,可用於基本的圖像操作和處理任務。特別是子模塊scipy.ndimage,提供了在n維NumPy數組上操作的函數。該包目前包括線性和非線性濾波,二值形態學,B樣條插值和對象測量等功能函數。
資源
有關scipy.ndimage包提供的完整功能列表,請參閱下面的鏈接:
https://docs.scipy.org/doc/scipy/reference/tutorial/ndimage.html#correlation-and-convolution
用法
使用SciPy通過高斯濾波器進行模糊:
4. PIL/ Pillow
PIL( Python圖像庫 )是Python編程語言的一個免費庫,它支持打開、操作和保存許多不同的文件格式的圖像。然而, 隨著2009年的最後一次發布,它的開發停滯不前。但幸運的是還有有Pillow,一個PIL積極開發的且更容易安裝的分支,它能運行在所有主要的操作系統,並支持Python3。這個庫包含了基本的圖像處理功能,包括點運算、使用一組內置卷積核的濾波和色彩空間的轉換。
資源
文檔中有安裝說明,以及涵蓋庫的每個模塊的示例:
https://pillow.readthedocs.io/en/3.1.x/index.html
用法
在 Pillow 中使用 ImageFilter 增強圖像:
5. OpenCV-Python
OpenCV( 開源計算機視覺庫 )是計算機視覺應用中應用最廣泛的庫之一 。OpenCV-Python 是OpenCV的python版API。OpenCV-Python的優點不只有高效,這源於它的內部組成是用C/C++編寫的,而且它還容易編寫和部署(因為前端是用Python包裝的)。這使得它成為執行計算密集型計算機視覺程序的一個很好的選擇。
資源
OpenCV-Python-Guide指南可以讓你使用OpenCV-Python更容易:
https://github.com/abidrahmank/OpenCV2-Python-Tutorials
用法
下面是一個例子,展示了OpenCV-Python使用金字塔方法創建一個名為「Orapple」的新水果圖像融合的功能。
6. SimpleCV
SimpleCV 也是一個用於構建計算機視覺應用程序的開源框架。有了它,你就可以訪問幾個高性能的計算機視覺庫,如OpenCV,而且不需要先學習了解位深度、文件格式、顏色空間等。
它的學習曲線大大小於OpenCV,正如它們的口號所說「計算機視覺變得簡單」。一些支持SimpleCV的觀點有:
即使是初學者也可以編寫簡單的機器視覺測試攝像機、視頻文件、圖像和視頻流都是可互操作的資源
官方文檔非常容易理解,而且有大量的例子和使用案例去學習:
https://simplecv.readthedocs.io/en/latest/
用法
7. Mahotas
Mahotas 是另一個計算機視覺和圖像處理的Python庫。它包括了傳統的圖像處理功能例如濾波和形態學操作以及更現代的計算機視覺功能用於特徵計算,包括興趣點檢測和局部描述符。該介面是Python語言,適合於快速開發,但是演算法是用C語言實現的,並根據速度進行了調優。Mahotas庫速度快,代碼簡潔,甚至具有最小的依賴性。通過原文閱讀它們的官方論文以獲得更多的了解。
資源
文檔包括安裝指導,例子,以及一些教程,可以更好的幫助你開始使用mahotas。
https://mahotas.readthedocs.io/en/latest/install.html
用法
Mahotas庫依賴於使用簡單的代碼來完成任務。關於『Finding Wally』的問題,Mahotas做的很好並且代碼量很少。下面是源碼:
https://mahotas.readthedocs.io/en/latest/wally.html
8. SimpleITK
ITK 或者 Insight Segmentation and Registration Toolkit是一個開源的跨平台系統,為開發人員提供了一套廣泛的圖像分析軟體工具 。其中, SimpleITK是建立在ITK之上的簡化層,旨在促進其在快速原型設計、教育、解釋語言中的應用。SimpleITK 是一個圖像分析工具包,包含大量支持一般過濾操作、圖像分割和匹配的組件。SimpleITK本身是用C++寫的,但是對於包括Python以內的大部分編程語言都是可用的。
資源
大量的Jupyter Notebooks 表明了SimpleITK在教育和研究領域已經被使用。Notebook展示了用Python和R編程語言使用SimpleITK來進行互動式圖像分析。
http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/
用法
下面的動畫是用SimpleITK和Python創建的剛性CT/MR匹配過程的可視化 。點擊此處可查看源碼!
9. pgmagick
pgmagick是GraphicsMagick庫的一個基於python的包裝。 GraphicsMagick圖像處理系統有時被稱為圖像處理的瑞士軍刀。它提供了一個具有強大且高效的工具和庫集合,支持以88種主要格式(包括重要格式,如DPX、GIF、JPEG、JPEG-2000、PNG、PDF、PNM和TIFF)讀取、寫入和操作圖像。
資源
有一個專門用於PgMagick的Github庫 ,其中包含安裝和需求說明。還有關於這個的一個詳細的用戶指導:
https://github.com/hhatto/pgmagick
用法
使用pgmagick可以進行的圖像處理活動很少,比如:
圖像縮放
邊緣提取
10. Pycairo
Pycairo是圖像處理庫cairo的一組Python捆綁。Cairo是一個用於繪制矢量圖形的2D圖形庫。矢量圖形很有趣,因為它們在調整大小或轉換時不會失去清晰度 。Pycairo是cairo的一組綁定,可用於從Python調用cairo命令。
資源
Pycairo的GitHub庫是一個很好的資源,有關於安裝和使用的詳細說明。還有一個入門指南,其中有一個關於Pycairo的簡短教程。
庫:https://github.com/pygobject/pycairo指南:https://pycairo.readthedocs.io/en/latest/tutorial.html用法
使用Pycairo繪制線條、基本形狀和徑向梯度:
總結
有一些有用且免費的Python圖像處理庫可以使用,有的是眾所周知的,有的可能對你來說是新的,試著多去了解它們。