1. Phân tích các yêu cầu
a) Các yêu cầu
• Trong báo cáo này ta sẽ viết một chương trình minh họa cho hai thuật toán là K-means và Fuzzy C-Means Clustering. Dữ liệu để kiểm tra là các ảnh chụp não của máy MR hoặc CT.
• Chương trình minh họa phải cho ta thấy được quá trình phân đoạn thay đổi khi các yếu tố là số cụm, số vòng lặp và độ phần trăm chính xác thay đổi. Ngoài ra, chương trình còn phải cho phép người sử dụng có thể thay đổi các yếu tố số cụm cần phân đoạn (cluster), số vòng lặp (Iteration) và độ chính xác, hiển thị trạng thái xử lý.
b) Môi trường và ngôn ngữ cài đặt
Chương trình được viết bằng ngôn ngữ Visual C# 2010, sử dụng .NET Framework 4.0.
2. Pseudo-Code
a) K-means
Bước 1: Khởi tạo. Chọn K trọng tâm {ci} (i = 1…K).
Bước 2: Tính toán khoảng cách. Công thức Euclide dùng để tính khoảng cách (t là số lần lặp):
Bước 3: Cập nhật lại trọng tâm
Bước 4: Điều kiện dừng. Lặp lại các bước 2 và 3 cho tới khi không có sự thay đổi trọng tâm của cụm.
b) Fuzzy C-Means
Bước 1: Khởi tạo số lượng cụm cần phân đoạn. Bước 2: Khởi tạo ma trận phân vùng mờ. Bước 3: Đặt biến vòng lặp k=0.
Bước 4: Tính toán các trọng tâm của cụm, tính giá tri của hàm mục tiêu J. Bước 5: Chạy vòng lặp for mỗi điểm ảnh, vòng lặp for cho mỗi cụm, tính toán tất cả các giá trị thành viên trong ma trân.
Bước 6: Nếu giá trị của J sau mỗi vòng lặp nhỏ hơn điều kiện dừng thì dừng vòng lặp, ngược lại, tăng giá trị k = k + 1 và quay lại bước 4.
Bước 7: Tiến hành giải mờ và phân đoạn
Giải thích các biến, phương thức sử dụng:
STT Tên biến/phương thức/lớp Kiểu dữ liệu Giải thích
1 ClusterCentroid Lớp (class) này dùng để biểu diễn trọng tâm trong cụm mờ
2 BSum double Biến này dùng để lưu tổng giá trị của các điểm ảnh trong cụm có màu xanh biển (Blue)
3 GSum double Biến này dùng để lưu tổng giá trị của các điểm ảnh trong cụm có màu xanh lá cây (Green)
4 MembershipSum double Biến này dùng để lưu tổng giá trị thành viên của tất cả các điểm ảnh trong cụm
5 OriginalPixelColor Color Biến này dùng để lưu giá trị màu sắc ban đầu của điểm ảnh trong cụm 6 PixelColor Color Biến này dùng để lưu giá trị màu sắc
của điểm ảnh trong cụm
7 RSum double Biến này dùng để lưu tổng giá trị của các điểm ảnh trong cụm có màu đỏ (Red)
8 X double Biến này dùng để lưu vị trí x của trọng tâm
trọng tâm
10 ClusterCentroid Phương thức này dùng để khởi tạo đối tượng ClusterCentroid
11 ClusterPoint Lớp (class) này dùng để biểu diễn điểm trong cụm mờ
12 ClusterIndex double Biến này dùng để lưu giữ vị trí của cụm
13 OriginalPixelColor Color Biến này dùng để lưu giá trị màu sắc ban đầu của điểm ảnh
14 PixelColor Color Biến này dùng để lưu giá trị màu sắc của điểm ảnh
15 X double Biến này dùng để lưu vị trí x của điểm ảnh
16 Y double Biến này dùng để lưu vị trí y của điểm ảnh
17 FuzzyCMeanAlgorithm Lớp (class) này dùng để xử lý phân cụm mờ 18 Clusters List Biến này dùng để lưu danh sách tất
cả các cụm
19 Eps double Biến này dùng để lưu giá trị độ chính xác của thuật toán
20 Fuzzyness double Biến này dùng để lưu giá trị của tham số mờ hóa
21 isConverged bool Biến này dùng để kiểm tra ảnh đã xử lý hay chưa
22 myImage Bitmap Biến này dùng để lưu ảnh dưới dạng bitmap
23 myImageHeight int Biến này dùng để lưu chiều cao của ảnh
24 myImageWidth int Biến này dùng để lưu chiều rộng của ảnh
25 Points List Biến này dùng để chứa danh sách tất cả các điểm ảnh
26 processedImage Bitmap Biến này dùng để lưu ảnh đang xử lý dưới dạng bitmap
27 Converged Bitmap Biến này dùng để lưu ảnh đã xử lý xong dưới dạng bitmap
28 getProcessedImage Bitmap Biến này dùng để lấy ảnh đã xử lý dưới dạng bitmap
29 J double Biến này dùng lưu giá trị của hàm
mục tiêu
30 CaculateClusterCentroids void Phương thức này dùng để tính số trọng tâm của 1 cụm
31 CalculateEuclideanDistan ce
double Phương thức này dùng để tính khoảng cách giữa 1 điểm ảnh tới 1 trọng tâm trong cụm theo công thức của Euclide
32 CalculateObjectiveFuncti on
double Phương thức này dùng để tính giá trị hàm mục tiêu
33 FuzzyCMeanAlgorithm Phương thức này dùng để khởi tạo các điểm ảnh và số cụm mờ
34 RecalculateClusterMemb ershipValues
void Phương thức này dùng để tính lại tổng giá trị của tất cả các thành viên của 1 điểm ảnh đến mọi cụm sao cho phải bằng 1
35 Step void Phương thức này dùng để gọi thực
thi các bước trong thuật toán 36 KMeanAlgorithm Lớp (class) này dùng để xử lý phân cụm rõ 37 clusters int Biến này dùng để lưu số lượng cụm 38 Distane double Biến này dùng để tính khoảng cách 39 Compute() void Hàm dùng tính khoảng cách từ các
điểm đến trọng tâm
40 Randomize void Hàm này dùng để chọn điểm ngẫu
nhiên trong các đối tượng
4. Hiện thực chương trình
Phần này sẽ trình bày một số chức năng chính của chương trình.
a) Khởi tạo danh sách chứa các đối tượng ClusterPoint cho các điểm ảnh trong cụm:
{
for (int col = 0; col < originalImage.Height; ++col)
{
Color c2 = originalImage.GetPixel(row, col);
points.Add(new ClusterPoint(row, col, c2));
}} }
b) Khởi tạo danh sách chứa các đối tượng ClusterCentroid (trọng tâm) trong cụm: List<ClusterCentroid> centroids = new
List<ClusterCentroid>();
//Create random points to use a the cluster centroids
Random random = new Random();
for (int i = 0; i < numClusters; i++)
{
int randomNumber1 = random.Next(sourceImage.Width);
int randomNumber2 = random.Next(sourceImage.Height);
centroids.Add(new ClusterCentroid(randomNumber1,
randomNumber2, filteredImage.GetPixel( randomNumber1, randomNumber2))); }
c) Phương thức tính khoảng cách Euclide
private double CalculateEuclideanDistance(ClusterPoint p,
ClusterCentroid c) {
return Math.Sqrt(Math.Pow(p.PixelColor.R -
c.PixelColor.R, 2.0) + Math.Pow(p.PixelColor.G -
c.PixelColor.G, 2.0) + Math.Pow(p.PixelColor.B -
c.PixelColor.B, 2.0)) } d) Phương thức tính giá trị hàm mục tiêu
public double CalculateObjectiveFunction() {
double Jk = 0.0;
for (int i = 0; i < this.Points.Count;i++)
{
for (int j = 0; j < this.Clusters.Count; j++)
{
Jk += Math.Pow(U[i, j], this.Fuzzyness) *
Math.Pow(this.CalculateEuclideanDistance(Point
s[i], Clusters[j]), 2); }
}
return Jk;
e) Phương thức tính các trọng tâm trong cụm
public void CalculateClusterCentroids() {
//Console.WriteLine("Cluster Centroid calculation:");
for (int j = 0; j < this.Clusters.Count; j++)
{
ClusterCentroid c = this.Clusters[j];
double l = 0.0; c.PixelCount = 1; c.RSum = 0; c.GSum = 0; c.BSum = 0; c.MembershipSum = 0;
for (int i = 0; i < this.Points.Count; i++)
{
ClusterPoint p = this.Points[i];
l = Math.Pow(U[i, j], this.Fuzzyness);
c.RSum += l * p.PixelColor.R; c.GSum += l * p.PixelColor.G; c.BSum += l * p.PixelColor.B; c.MembershipSum += l; if (U[i, j] == p.ClusterIndex) { c.PixelCount += 1; } }
c.PixelColor = Color.FromArgb((byte)(c.RSum /
c.MembershipSum), (byte)(c.GSum / c.MembershipSum),
(byte)(c.BSum / c.MembershipSum));
}
//update the original image
Bitmap tempImage = new
Bitmap(myImageWidth,myImageHeight,
PixelFormat.Format32bppRgb);
for (int j = 0; j < this.Points.Count; j++)
{
for (int i = 0; i < this.Clusters.Count; i++)
{
ClusterPoint p = this.Points[j];
if (U[j, i] == p.ClusterIndex)
{
tempImage.SetPixel((int)p.X, (int)p.Y,
this.Clusters[i].PixelColor);
} } }
processedImage = tempImage; }
5. Giao diện chương trình
Chương trình cho phép người dùng chọn các thông số (được đánh số như hình bên dưới):
- Phân cụm ảnh theo K-means (1) - Phân cụm ảnh theo FCM (2) - Số cụm cần phân đoạn (3).
- Số vòng lặp chạy tối đa (4) (trường hợp tập điểm ảnh có số lượng nhỏ và phân cụm nhỏ, thì số vòng lặp xử lý thực tế có thể sẽ nhỏ hơn thông số này).
- Độ chính xác (5).
Sau đây là một số hình ảnh xử lý phân cụm mờ của chương trình.
c) Kết quả phân cụm ảnh chụp màu đã xử lý theo K-means