Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 26

BÀI 3: THỰC HIỆN CÁC

KĨ THUẬT
PHÂN ĐOẠN ẢNH
GVHD: Đặng Nguyên Châu
3.1 Đọc ảnh Mushroom1 và vẽ histogram của ảnh:
Đầu tiên chúng ta cần tạo thư viện hỗ trợ:
from PIL import Image
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as st
Đọc ảnh Mushroom1:
Image_1 = Image.open('/content/Mushroom1.jpg')
In kích thước và ma trận ảnh
image_1 = np.array(image_1)
print('Kích thước của ảnh: ',image_1.shape)
image_1
Đưa ma trận ảnh qua file Excel:   plt.xlim(mn, mx)
df = pd.DataFrame(image_1)
  kde_xs = np.linspace(mn, mx, 301)
df.to_csv('matrix_img_before_KT1_KT2.csv',index=Fa
  kde = st.gaussian_kde(image)
lse)
  plt.plot(kde_xs, kde.pdf(kde_xs), label="PDF") #PDF:
Duỗi thẳng ma trận ảnh Mushroom1:
 Probability Density Function
image_1 = image_1.reshape(-1)
  plt.legend(loc="center")
image_1
  plt.ylabel('Probability')
Vẽ histogram của ảnh Mushroom1:
  plt.xlabel('Value of pixel')
def visual_hist(image):
  plt.title("Histogram of image");
  plt.hist(image, density=True, bins=30, label="Data")
 
  mn, mx = plt.xlim()
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 1:

Kỹ thuật 1 chọn mức xám T dựa trên cực đại giữa hai nhóm object và
Background. Giả sử với một mức xám T cho trước, các pixel trong ảnh xám sẽ
được chia thành hai nhóm với giá trị mức xám trung bình là A1 và A2. Gọi A là
mức xám trung bình của bức ảnh. Phương sai giữa hai nhóm được tính như sau:

trong đó và lần lượt là xác suất của 02 nhóm.

Xây dựng hàm tính giá trị mức xám trung bình A1, A2 và xác suất , của hai
nhóm:

def Function_name_2( image, T):

  '''
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 1:
Hàm tính giá trị sigma tương ứng với mỗi T:
 else:
  In ra ảnh output
      p_ = 255
  pixel_ = []
      A_2 +=i
  count, count_1, count_2 = 0, 0, 0
      count_2 += 1
  P_1 ,P_2 = 0,0
    pixel_.append(p_)
  A, A_1, A_2 = 0, 0 ,0
  # So sánh và phân loại 2 object   P_1 = count_1 /count
  for i in image:   P_2 = count_2 /count
    A += i   if count_1 != 0:
    count +=1     A_1 = A_1 / count_1
    if i < T:   if count_2 != 0:
      p_ = 0     A_2 = A_2 / count_2
      A_1 += i   A = A / count
      count_1 += 1
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 1:

Biểu thức sigma ứng với mỗi giá trị mức xám T:
#Tìm giá trị T sao cho sigma là lớn nhất
#Biểu thức sigma
for T in range(256):
  sigma = P_1*(A_1 - A)*(A_1 - A) + P_2*(A_2 -
 A)*(A_2 - A)   sigma_ , pixel = Function_name_2( image_1, T)

  return sigma, pixel_   sigma.append(sigma_)

Giá trị mức xám T được chọn làm cho sigma đạt   if sigma_ > max:
cực đại:     max = sigma_
max = 0     value_T = T
value_T = 0
sigma = []
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 1:

Vẽ đồ thị liên hệ giữa T và sigma. In ra giá trị T:

plt.plot(sigma)

print('Value of T:', value_T)

sigma, pixel = Function_name_2(image_1, value_T)
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 1:

Tạo file excel lưu kết quả:


pixel = np.array(pixel) Đây là ảnh sau khi phân đoạn với giá trị T tìm được,
T=110:
pixel = pixel.reshape(426, 640)
 
df = pd.DataFrame(pixel)
df.to_csv('matrix_img_after_KT2.csv',index=False)
 
cv.imwrite('image_result_KT2.jpg', pixel)
image_result = Image.open('image_result_KT2.jpg')
image_result
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 2

Mức xám T được được chọn dựa trên xác suất Bayes và sự giả định tương đồng nhau giữa các
ảnh có cùng tính chất. Xét ảnh Mushroom1, gọi và lần lượt là các vùng object và backgound.
Xét một mức xám T, xác suất Bayes mà một mức xám T thuộc về vùng object sẽ là:

Trong đó, là xác suất của mức xám T trong vùng object và là xác suất của vùng object, tổng
xác suất của mức xám T. Tương tự, xác suất mà mức xám T thuộc về vùng background là:
3.2. Thực hiện phân đoạn ảnh Mushroom1 bằng Kỹ thuật 2
Trong đó, là xác suất của mức xám T trong vùng background và là xác suất của vùng background,
tổng xác suất của mức xám T.

Mức xám T được chọn là mức xám làm cho:

Tuy nhiên vấn đề đặt ra của kỹ thuật này là để tính xác suất của mức xám T trong một nhóm nào đó,
chúng ta cần phải biết phân bố xác suất của nhóm đó. Giả sử là phân bố Gaussian, chúng ta phải tìm
được giá trị trung bình và phương sai của phân bố đó. Với điều này, người ta có thể dựa vào sự giả sử
tương đồng giữa các ảnh gần giống nhau. Ví dụ ta có một ảnh Mushroom2 như sau. Chúng ta có thể
dựa vào ảnh Mushroom 2 để xây dựng phân bố xác suất mức xám cho các vùng object và background.
Sau đó dùng các phân bố này áp dụng ngược lại cho ảnh Mushroom1 với giả sử các ảnh tương đồng
nhau, để tìm mức xám T tối ưu (dựa vào xác suất Bayes) cho ảnh Mushroom1.

 
3.3.1 Thực hiện phân đoạn ảnh Mushroom2 bằng Kỹ thuật 1:

Tương tự như mục 2.2, chúng ta sẽ phân đoạn ảnh Musshroom 2 bằng
kĩ thuât 1

Đọc ảnh Musshroom 2:

image_2 = Image.open('/content/Mushroom2.jpg')

image_2 = np.array(image_2)

image_2 = image_2.reshape(-1)

image_2

Vẽ histogram của ảnh Mushroom2:

visual_hist(image_2)
3.3.1 Thực hiện phân đoạn ảnh Mushroom2 bằng Kỹ thuật 1:
Xây dựng hàm tìm giá trị mức xám T cho ảnh Mushroom2:
T = 0
d = 0
while True:
  pixel, A_1, A_2 = Function_name_1( image_2, T)
  T_value = int((A_1 + A_2) / 2)
  d+=1
  if T_value != T:
    T = T_value
  else:
Break
In ra giá trị T và A1, A2:
print('Value of T: ',T)
print(A_1, A_2)
3.4.2 Uớc lượng giá trị trung bình và phương sai của các vùng object và
background trong ảnh Mushroom2. Vẽ hai phân bố vừa tìm được.

Tiếp tục, chúng ta dựa vào mức xám T vừa để phân đoạn ảnh Mushroom2, tiến hành xác định xác
pixel nào trong ảnh Mushroom2 thuộc về các vùng object và background. Với từng vùng này, giả
sử mức xám trong mỗi vùng có phân bố Gaussian. Các giá trị trung bình và phương sai của các
phân và bố thỏa mãn:
3.3.2 Uớc lượng giá trị trung bình và phương sai của các vùng object và background trong
ảnh Mushroom2. Vẽ hai phân bố vừa tìm được.
Trước hết chúng ta cần phân loại những mức xám  if i not in count_dict_A1:
nào thuộc A1 hoặc A2:
        count_dict_A1[i] = 1
def Function_name_3(image,T):
      else:
  A_1, A_2 = 0, 0
        count_dict_A1[i] += 1
  count_A1, count_A2 = 0,0
    else:
  count_dict_A1 = {}
      #A_2 += i
  count_dict_A2 = {}
      #count_A2 +=1
  # Tính A1, A2
      if i not in count_dict_A2:
  for i in image:
        count_dict_A2[i] = 1
    if i > T:
      else:
      #A_1 += i
        count_dict_A2[i] += 1
      #count_A1 +=1
     
3.3.2 Uớc lượng giá trị trung bình và phương sai của các vùng object và background trong
ảnh Mushroom2. Vẽ hai phân bố vừa tìm được.
Tìm xác suất trong các vùng A1 và A2:
  #A_1 /= count_A1 Tìm các giá trị A1, A2 và ứng với A1 và A2:

  #A_2 /= count_A2   sum_A1, sum_A2 = 0, 0
  # Tính xác suất trong A1, A2
  for c1 in count_dict_A1:
  sum_count_A1, sum_count_A2 = 0,0
  for c1 in count_dict_A1:     A_1 += c1*count_dict_A1[c1]

    sum_count_A1 += count_dict_A1[c1]     sum_A1 = sum_A1 + (c1**2)*count_dict_A1[c1]
  for c2 in count_dict_A2:
 
    sum_count_A2 += count_dict_A2[c2]
  for c1 in count_dict_A1:   for c2 in count_dict_A2:

    count_dict_A1[c1] /= sum_count_A1     A_2 += c2*count_dict_A2[c2]
  for c2 in count_dict_A2:
    sum_A2 = sum_A2 + (c2**2)*count_dict_A2[c2]
    count_dict_A2[c2] /= sum_count_A2
3.3.2 Uớc lượng giá trị trung bình và phương sai của các vùng object và background trong
ảnh Mushroom2. Vẽ hai phân bố vừa tìm được.
Tính các giá trị và :
  print('xi*xi*pi: ------', sum_A1, sum_A2)
  sigma_1 = sqrt((sum_A1 - A_1*A_1))
  sigma_2 = sqrt((sum_A2 - A_2*A_2))
  return A_1, A_2, sigma_1, sigma_2
In các giá trị và :
A_1, A_2, sigma_1 , sigma_2 = Function_name_3(image_2,88)
print('A1, A2: -------', A_1, A_2)
print('sigma:-------' , sigma_1, sigma_2)
3.3.2 Uớc lượng giá trị trung bình và phương sai của các vùng object và background trong
ảnh Mushroom2. Vẽ hai phân bố vừa tìm được.
Với từng vùng này, giả sử mức xám trong mỗi vùng có phân bố Gaussian với hàm mật độ xác suất:

Xây dựng hàm mật độ xác suất:


def gaussian(x, mu, sig):
    return (np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.))))
Đồ thị hai phân bố vừa ước lượng ứng với và :
x_values = np.linspace(-2500,2500, 100000)
for mu, sig in [(A_1, sigma_1), (A_2, sigma_2)]:
    plt.plot(x_values, gaussian(x_values, mu, sig))
plt.axis([-150,300,0,1.2])
plt.plot([88,88],[0, 1],'--' )
plt.plot([160,160],[0, 1],'--' )
3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes

Với các phân bố này vừa tìm được ở mục 2.4.2, chúng áp dụng lại vào ảnh Mushroom1 để tìm giá trị T
theo xác suất Bayes.
Có thể giả sử trong ảnh Mushroom1, diện tích của vùng object chiếm 60% diện tích của bức ảnh.
Điều đó đồng nghĩa với:

Mức xám T được chọn là mức xám làm cho:

Do đó:

Xác suất trong một vùng bất kì được tính như:


3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes

Tuy nhiên tích phân trên không tồn tại nguyên hàm, điều này ảnh hưởng tới việc
khó tìm được kết quả bài toán. Mặc dù vậy, chúng ta vẫn tính được tích phân
trên dựa trên việc lấy xấp xỉ bằng công thức hình thang mở rộng. Cụ thể như
sau:

Để tính tích phân ta chia đoạn thành n đoạn bằng nhau bởi các điểm chia:
3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes

Áp dụng công thức hình thang trên mỗi đoạn

Sử dụng công thức trên cho bài toán này, với một giá trị của cho trước, chúng ta chia đoạn
thành đoạn với . Khi đó:
3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes

Thực hiện cho T chạy từ 0->255, chúng ta sẽ có các tỉ số khác nhau.


Tuy nhiên phương pháp trên sử dụng phép lấy xấp xỉ nên chúng ta không
thể tính được chính xác tỉ số . Do đó chúng ta có thể ước lượng như sau:

Giá trị của T được chọn là giá trị làm cho giá trị của ở biểu thức trên đạt
giá trị nhỏ nhất.
3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes

Xây dựng hàm tính tích phân theo công thức hình thang mở rộng với mỗi giá trị T:
def TichPhan(T):
  # h = 1
  x = np.linspace(-150,T,T+151)
  y1 = f(x,A_1, sigma_1)
  y2 = f(x,A_2, sigma_2)
  P1 = y1[0] + y1[-1]
  P2 = y2[0] + y2[-1]
  for i in range(1,len(x)-1):
    P1 += 2*y1[i]
    P2 += 2*y2[i]
  P1 = P1/2
  P2 = P2/2
  return P1, P2
3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes
Giá trị T được chọn làm cho error đạt giá trị nhỏ nhất:

min = 1000 pixel_3 , A1, A2 = Function_name_1(image_1, T_value)

T_value = 0 pixel = np.array(pixel_3)

for T in range(256): pixel = pixel.reshape(426, 640)

  P1, P2 = TichPhan(T)

  error = abs(P1/P2 - 2/3)

  if error < min:

    min = error

    T_value = T

T_value
3.3.3 Thực hiện phân đoạn ảnh Mushroom1 dựa theo xác suất Bayes

Tạo file lưu kết quả: Đây là ảnh sau khi phân đoạn với giá trị T tìm được, T=160:
df = pd.DataFrame(pixel)
df.to_csv('matrix_img_after_KT3.csv',index=False)
cv.imwrite('image_result_KT3.jpg', pixel)
image_result = Image.open('image_result_KT3.jpg')
image_result
3.4 KẾT LUẬN:

Khi thực hiện phân đoạn ảnh Mushroom1, các kết quả
phân đoạn bằng Kỹ thuật 1 (T=109) và Kỹ thuật 2
(T=110) là tương tự nhau. Tuy nhiên, kết quả phân đoạn
bằng Kỹ thuật 3 (T=160) sai lệch nhiều so với hai kết quả
trên. Để giải thích cho sai lệch này, chúng ta phải kể đến
việc sai số khi lấy xấp xỉ tích phân bằng công thức hình
thang mở rộng mở mục 2.4.3.

You might also like