我聽說過關於mahotas的this教程,希望能夠在python中找到Zernike多項式的良好實現。這不可能更容易。然而,我需要比較原始圖像和Zernike矩重構的歐幾里得之間的差異。如果他可以將重建功能添加到他的圖書館,但他沒有時間去創建它,使用mahotas和opencv基於Zernike矩的圖像重建
如何使用mahotas提供的Zernike時刻在OpenCV中重建圖像?
我聽說過關於mahotas的this教程,希望能夠在python中找到Zernike多項式的良好實現。這不可能更容易。然而,我需要比較原始圖像和Zernike矩重構的歐幾里得之間的差異。如果他可以將重建功能添加到他的圖書館,但他沒有時間去創建它,使用mahotas和opencv基於Zernike矩的圖像重建
如何使用mahotas提供的Zernike時刻在OpenCV中重建圖像?
基於code,在他的答案中提到的fireant,我開發了以下重建代碼。我還發現研究論文[A. Khotanzad and Y. H. Hong, 「Invariant image recognition by Zernike moments」]和[S.-K. Hwang and W.-Y. Kim, 「A novel approach to the fast computation of Zernike moments」]非常有用。
函數_slow_zernike_poly構造2維Zernike基函數。在zernike_reconstruct函數中,我們將圖像投影到由_slow_zernike_poly返回的基函數並計算矩。然後我們使用重建公式。
下面是一個例子重建使用此代碼完成的:
輸入圖像
使用重構圖像的實數部分順序12
'''
Copyright (c) 2015
Dhanushka Dangampola <[email protected]>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
'''
import numpy as np
from math import atan2
from numpy import cos, sin, conjugate, sqrt
def _slow_zernike_poly(Y,X,n,l):
def _polar(r,theta):
x = r * cos(theta)
y = r * sin(theta)
return 1.*x+1.j*y
def _factorial(n):
if n == 0: return 1.
return n * _factorial(n - 1)
y,x = Y[0],X[0]
vxy = np.zeros(Y.size, dtype=complex)
index = 0
for x,y in zip(X,Y):
Vnl = 0.
for m in range(int((n-l)//2) + 1):
Vnl += (-1.)**m * _factorial(n-m)/\
(_factorial(m) * _factorial((n - 2*m + l) // 2) * _factorial((n - 2*m - l) // 2)) * \
(sqrt(x*x + y*y)**(n - 2*m) * _polar(1.0, l*atan2(y,x)))
vxy[index] = Vnl
index = index + 1
return vxy
def zernike_reconstruct(img, radius, D, cof):
idx = np.ones(img.shape)
cofy,cofx = cof
cofy = float(cofy)
cofx = float(cofx)
radius = float(radius)
Y,X = np.where(idx > 0)
P = img[Y,X].ravel()
Yn = ((Y -cofy)/radius).ravel()
Xn = ((X -cofx)/radius).ravel()
k = (np.sqrt(Xn**2 + Yn**2) <= 1.)
frac_center = np.array(P[k], np.double)
Yn = Yn[k]
Xn = Xn[k]
frac_center = frac_center.ravel()
# in the discrete case, the normalization factor is not pi but the number of pixels within the unit disk
npix = float(frac_center.size)
reconstr = np.zeros(img.size, dtype=complex)
accum = np.zeros(Yn.size, dtype=complex)
for n in range(D+1):
for l in range(n+1):
if (n-l)%2 == 0:
# get the zernike polynomial
vxy = _slow_zernike_poly(Yn, Xn, float(n), float(l))
# project the image onto the polynomial and calculate the moment
a = sum(frac_center * conjugate(vxy)) * (n + 1)/npix
# reconstruct
accum += a * vxy
reconstr[k] = accum
return reconstr
if __name__ == '__main__':
import cv2
import pylab as pl
from matplotlib import cm
D = 12
img = cv2.imread('fl.bmp', 0)
rows, cols = img.shape
radius = cols//2 if rows > cols else rows//2
reconst = zernike_reconstruct(img, radius, D, (rows/2., cols/2.))
reconst = reconst.reshape(img.shape)
pl.figure(1)
pl.imshow(img, cmap=cm.jet, origin = 'upper')
pl.figure(2)
pl.imshow(reconst.real, cmap=cm.jet, origin = 'upper')
這並不難,我想你可以自己編寫代碼。首先,記住每個時刻/矩陣的逆矩陣aka基礎圖像是矩陣的轉置,因爲它們是正交的。然後看看該庫的作者用來測試該功能的code。這比庫中的代碼更簡單,所以你可以閱讀和理解它是如何工作的(當然也比較慢)。你需要得到這些矩陣的每個時刻,這是基礎圖像。您可以修改_slow_znl
以獲取在主循環for x,y,p in zip(X,Y,P):
內計算的x,y
的值,並將其存儲在與輸入圖像大小相同的矩陣中。將白色圖像傳遞到_slow_zernike
,並獲得所有矩陣達到所需的徑向程度。使用係數重建圖像,就像使用哈爾變換一樣,使用這些矩陣的轉置。
謝謝!我正在玩這個代碼,但我錯了,你會介意我的錯誤嗎? http://pastebin.com/pAqibuqS我已經添加了有關我已經從原始代碼改變的評論。 –
mahotas的作者在這裏:你會考慮將這個代碼的清理版本提交給包嗎?或者明確地將其許可爲MIT,以便可以由其他人集成?謝謝 – luispedro
@luispedro我將它授權爲MIT。請檢查它並讓我知道是否需要更改。說實話,我對許可不是很熟悉。 – dhanushka
@luispedro我從上面的代碼中刪除了MIT許可證。我讀到SO中的代碼是在Creative Commons許可下,所以我不確定我是否在MIT下授權此代碼來違反SO條款。我認爲更好的選擇是將這個版本提交給你的圖書館。請指教。 – dhanushka