matlab qtdecomp,Opencv图像识别从零到精通(25)------区域分裂与合并
區(qū)域分割一般認為有漫水填充,區(qū)域分裂與合并,分水嶺,這篇是中間的區(qū)域分裂和合并。
區(qū)域分裂合并算法的基本思想是先確定一個分裂合并的準則,即區(qū)域特征一致性的測度,當圖像中某個區(qū)域的特征不一致時就將該區(qū)域分裂成4個相等的子區(qū)域,當相鄰的子區(qū)域滿足一致性特征時則將它們合成一個大區(qū)域,直至所有區(qū)域不再滿足分裂合并的條件為止.當分裂到不能再分的情況時,分裂結(jié)束,然后它將查找相鄰區(qū)域有沒有相似的特征,如果有就將相似區(qū)域進行合并,最后達到分割的作用。在一定程度上區(qū)域生長和區(qū)域分裂合并算法有異曲同工之妙,互相促進相輔相成的,區(qū)域分裂到極致就是分割成單一像素點,然后按照一定的測量準則進行合并,在一定程度上可以認為是單一像素點的區(qū)域生長方法。區(qū)域生長比區(qū)域分裂合并的方法節(jié)省了分裂的過程,而區(qū)域分裂合并的方法可以在較大的一個相似區(qū)域基礎(chǔ)上再進行相似合并,而區(qū)域生長只能從單一像素點出發(fā)進行生長(合并)。
反復(fù)進行拆分和聚合以滿足限制條件的算法。
令R表示整幅圖像區(qū)域并選擇一個謂詞P。對R進行分割的一種方法是反復(fù)將分割得到的結(jié)果圖像再次分為四個區(qū)域,直到對任何區(qū)域Ri,有P(Ri)=TRUE。這里是從整幅圖像開始。如果P(R)=FALSE,就將圖像分割為4個區(qū)域。對任何區(qū)域如果P的值是FALSE.就將這4個區(qū)域的每個區(qū)域再次分別分為4個區(qū)域,如此不斷繼續(xù)下去。這種特殊的分割技術(shù)用所謂的四叉樹形式表示最為方便(就是說,每個非葉子節(jié)點正好有4個子樹),這正如圖10.42中說明的樹那樣。注意,樹的根對應(yīng)于整幅圖像,每個節(jié)點對應(yīng)于劃分的子部分。此時,只有R4進行了進一步的再細分。
如果只使用拆分,最后的分區(qū)可能會包含具有相同性質(zhì)的相鄰區(qū)域。這種缺陷可以通過進行拆分的同時也允許進行區(qū)域聚合來得到矯正。就是說,只有在P(Rj∪Rk)=TRUE時,兩個相鄰的區(qū)域Rj和Rk才能聚合。
前面的討論可以總結(jié)為如下過程。在反復(fù)操作的每一步,我們需要做:
l.對于任何區(qū)域Ri,如果P(Ri)=FALSE,就將每個區(qū)域都拆分為4個相連的象限區(qū)域。
2.將P(Rj∪Rk)=TRUE的任意兩個相鄰區(qū)域Rj和Rk進行聚合。
3.當再無法進行聚合或拆分時操作停止。
可以對前面講述的基本思想進行幾種變化。例如,一種可能的變化是開始時將圖像拆分為一組圖象塊。然后對每個塊進一步進行上述拆分,但聚合操作開始時受只能將4個塊并為一組的限制。這4個塊是四叉樹表示法中節(jié)點的后代且都滿足謂詞P。當不能再進行此類聚合時,這個過程終止于滿足步驟2的最后的區(qū)域聚合。在這種情況下,聚合的區(qū)域可能會大小不同。這種方法的主要優(yōu)點是對于拆分和聚合都使用同樣的四叉樹,直到聚合的最后一步。
例10.17拆分和聚合
圖10.43(a)顯示了一幅簡單的圖像。如果在區(qū)域Ri內(nèi)至少有80%的像素具有zj-mi≤2σi的性質(zhì),就定義P(Ri)=TRUE,這里zj是Ri內(nèi)第j個像素的灰度級,mi是區(qū)域Ri的灰度級均值,σi是區(qū)域Ri內(nèi)的灰度級的標準差。如果在此條件下,P(Ri)=TRUE,則設(shè)置Ri內(nèi)的所有像素的值等于mi。拆分和聚合使用前速算法的要點完成。將這種技術(shù)應(yīng)用于圖10.43(a)所得結(jié)果示于圖10.43(b)。請注意,圖像分割效果相當好。示于圖10.43(c)中的圖像是通過對圖10.43(a)進行門限處理得到的,門限值選在直方圖中兩個主要的尖峰之間的中點。經(jīng)過門限處理,圖像中生成的陰影(和葉子的莖)被錯誤地消除了。
如前面的例子中所使用的屬性那樣,我們試圖使用基于區(qū)域中像素的均值和標準差的某些特性對區(qū)域的紋理進行量化(見11.3.3節(jié)中關(guān)于紋理的討論)。紋理分割的概念是以在謂詞P(Ri)中使用有關(guān)紋理的量度為基礎(chǔ)的。就是說,通過指定基于紋理內(nèi)容的謂詞,我們可以使用本節(jié)中討論的任何方法進行紋理分割。
1. 把一幅圖像分成4份,計算每一份圖像的最大灰度值與最小灰度值的差,?如果差在誤差范圍值外,則該份圖像繼續(xù)分裂。
2. 對于那些不需要分裂的那些份圖像可以對其進行閾值切割了,例如某一塊圖像的最大灰度大于某個值,則該塊圖像變成255,否則變?yōu)?。
// 代碼
// 區(qū)域分裂合并的圖像分割
// nOffSetLne是行偏移量
// 由于分裂的層數(shù)太多了, 使用遞歸將使內(nèi)存空間堆棧溢出
// 解決方法是使用一個堆棧對要分裂的塊入棧
// 使用堆棧的方法類似在"區(qū)域生長"的實現(xiàn)方法
#include
struct SplitStruct
{
unsigned int nWidth; // 這一塊圖像的寬度
unsigned int nHeigh; // 這一塊圖像的高度
unsigned int nOffSetWidth; // 相對源圖像數(shù)據(jù)的偏移寬度
unsigned int nOffSetHeigh; // 相對源圖像數(shù)據(jù)的偏移高度
};
void AreaSplitCombineEx(BYTE* image0, // 源圖像數(shù)據(jù)
unsigned int nAllWidth, // 源圖像的寬度
unsigned int nAllHeigh, // 源圖像的高度
unsigned int w, // 這一塊圖像的寬度
unsigned int h, // 這一塊圖像的高度
unsigned int nOffSetWidth, // 相對源圖像數(shù)據(jù)的偏移寬度
unsigned int nOffSetHeigh) // 相對源圖像數(shù)據(jù)的偏移高度
{
std::stack nMyStack;
SplitStruct splitStruct, splitStructTemp;
splitStruct.nWidth = w;
splitStruct.nHeigh = h;
splitStruct.nOffSetWidth = nOffSetWidth;
splitStruct.nOffSetHeigh = nOffSetHeigh;
nMyStack.push(splitStruct);
int i, j;
int nValueS[2][2]; // 用于存儲塊圖像的屬性值(該屬性值= 該塊圖像的所有像素灰度值之和除以該塊圖像所有像素點的數(shù)量)
int nAV;
int nWidthTemp[3], nHeightTemp[3], nTemp;
int nWidth, nHeigh;
int n, m, l;
double dOver;
while(!nMyStack.empty())
{
splitStruct = nMyStack.top();
nMyStack.pop();
n = (splitStruct.nOffSetHeigh * nAllWidth + splitStruct.nOffSetWidth); // 該塊圖像的左上角
// 1. 把圖像分成2 * 2 塊,
nWidthTemp[0] = 0;
nWidthTemp[2] = (splitStruct.nWidth + 1) / 2;
nWidthTemp[1] = splitStruct.nWidth - nWidthTemp[2];
nHeightTemp[0] = 0;
nHeightTemp[2] = (splitStruct.nHeigh + 1) / 2;
nHeightTemp[1] = splitStruct.nHeigh - nHeightTemp[2];
// 計算每一塊圖像的屬性值
int nValue;
int nValueTemp;
nAV = 0;
for(i = 1; i < 3; ++i)
{
for(j = 1; j < 3; ++j)
{
nValue = 0;
m = (n + nAllWidth * nHeightTemp[i - 1] + nWidthTemp[j - 1]);
for(nHeigh = 0; nHeigh < nHeightTemp[i]; ++nHeigh)
{
for(nWidth = 0; nWidth < nWidthTemp[j]; ++nWidth)
{
l = (m + nAllWidth * nHeigh + nWidth) * 4;
nValueTemp = (0.299 * image0[l] + 0.587 * image0[l + 1] + 0.114 * image0[l + 2]);
// 灰度值之和
nValue += nValueTemp;
}
}
if(nHeightTemp[i] * nWidthTemp[j] == 0)
{
continue;
}
if(nHeightTemp[i] * nWidthTemp[j] == 1)
{
l = m * 4;
if((0.299 * image0[l] + 0.587 * image0[l + 1] + 0.114 * image0[l + 2]) < 125)
// 這個值可以動態(tài)設(shè)定
{
image0[l] = image0[l + 1] = image0[l + 2] = 0;
image0[l + 3] = 255;
}
else
{
image0[l] = image0[l + 1] = image0[l + 2] = 255;
image0[l + 3] = 255;
}
continue;
}
// 各塊圖像的灰度平均值(每一塊圖像的屬性值)
nValueS[i - 1][j - 1] = nValue / (nHeightTemp[i] * nWidthTemp[j]);
// 2. 對每一塊進行判斷是否繼續(xù)分裂(注意分裂的原則)
// 我這里的分裂原則是: 圖像的屬性值在屬性值平均值的誤差范圍之內(nèi)就不分裂
if(nValueS[i - 1][j - 1] < 220) // 灰度平均值少于200 需要繼續(xù)分裂 // 這里就是分裂準則了
{
splitStructTemp.nWidth = nWidthTemp[j];
splitStructTemp.nHeigh = nHeightTemp[i];
splitStructTemp.nOffSetWidth = splitStruct.nOffSetWidth + nWidthTemp[j - 1];
splitStructTemp.nOffSetHeigh = splitStruct.nOffSetHeigh + nHeightTemp[i - 1];
nMyStack.push(splitStructTemp);
}
else // 合并(直接填充該塊圖像為黑色)
{
// 3. 如果不需要分裂, 則進行合并
for(nHeigh = 0; nHeigh < nHeightTemp[i]; ++nHeigh)
{
for(nWidth = 0; nWidth < nWidthTemp[j]; ++nWidth)
{
l = (m + nAllWidth * nHeigh + nWidth) * 4;
image0[l] = image0[l + 1] = image0[l + 2] = 255;
image0[l + 3] = 255;
}
}
}
}
}
}
return;
}
該代碼的效果也不是太好,主要是分裂準則不好確
區(qū)域分裂合并中?最初使用每塊圖像區(qū)域中極大與極小灰度值之差是否在允許的偏差范圍來作為均勻性測試準則。?后來均勻性測試準則又被不斷的發(fā)展。目前,統(tǒng)計檢驗,如均方誤差最小,?F檢測等都是最常用的均勻性測試準側(cè)方法
看均方誤差最小的情況
其中C是區(qū)域R中N個點的平均值。
相對于區(qū)域生長而言,區(qū)域分割于合并技術(shù)不再依賴于種子點的選擇與生長順序。但選用合適的均勻性測試準則P對于提高圖像分割質(zhì)量十分重要,當均勻性測試準則P選擇不當時,很容易會引起“方塊效應(yīng)”
參考連接;http://blog.csdn.net/bagboy_taobao_com/article/details/5666109
MATLAB
matlab中給出了qtdecomp().qtsetblk(),下面看看效果
I = imread('liftingbody.png');
S = qtdecomp(I,.27);%以閾值ceil(0.27*255)=69對圖像I進行四叉分解
blocks = repmat(uint8(0),size(S));%得到一個和I同尺寸的黑色背景blocks
for dim = [512 256 128 64 32 16 8 4 2 1]; %分塊全是2的整數(shù)次冪,注①
numblocks = length(find(S==dim)); %有numblocks個尺寸為dim的分塊,注③
if (numblocks > 0)
values = repmat(uint8(1),[dim dim numblocks]);%產(chǎn)生一個dim x dim x numblocks的三維1值矩陣(或說
% numblocks個尺寸為dim x dim的1值block)
values(2:dim,2:dim,:) = 0;
blocks = qtsetblk(blocks,S,dim,values);%blocks保存了所有塊被替換后的結(jié)果。注④
end
end
blocks(end,1:end) = 1;
blocks(1:end,end) = 1;
imshow(I), figure, imshow(blocks,[])
圖像識別算法交流 QQ群:145076161,歡迎圖像識別與圖像算法,共同學(xué)習(xí)與交流
原文:http://blog.csdn.net/qq_20823641/article/details/52191210
總結(jié)
以上是生活随笔為你收集整理的matlab qtdecomp,Opencv图像识别从零到精通(25)------区域分裂与合并的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python环境变量配置_Python的
- 下一篇: python仪表指针识别_一种指针式仪表