Bài giảng Xử lý ảnh - Chương 4: Phần mềm xử lý ảnh
lượt xem 11
download
Trong chương này, chúng ta sẽ nói về sự tổ chức của những chương trình máy tính thực hiện các phép toán. Đặc biệt, chúng ta sẽ xem xét phần mềm được thiết kế, phát triển và đưa ra cho người sử dụng như thế nào. Kiến thức về quá trình này có ích đối với các nhà phát triển và cũng như người sử dụng. Đối với các nhà phát triển, nó có thể tránh sự cố gắng uổng phí và sự thực hiện chán ngắt. Đối với người sử dụng, nó có thể trợ giúp sự định giá phần mềm và sự thực hiện dự án.
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Bài giảng Xử lý ảnh - Chương 4: Phần mềm xử lý ảnh
- CHƯƠNG 4 PHẦN MỀM XỬ LÝ ẢNH 4.1 GIỚI THIỆU Những phần khác của cuốn sách này sẽ nhằm vào các thuật giải sử dụng trong xử lý ảnh số và các thành phần phần cứng để thực hiện những công nghệ này. Trong chương này, chúng ta sẽ nói về sự tổ chức của những chương trình máy tính thực hiện các phép toán. Đặc biệt, chúng ta sẽ xem xét phần mềm được thiết kế, phát triển và đưa ra cho người sử dụng như thế nào. Kiến thức về quá trình này có ích đối với các nhà phát triển và cũng như người sử dụng. Đối với các nhà phát triển, nó có thể tránh sự cố gắng uổng phí và sự thực hiện chán ngắt. Đối với người sử dụng, nó có thể trợ giúp sự định giá phần mềm và sự thực hiện dự án. Chương này cung cấp một cái nhìn khái quát về những chủ đề quan trọng nêu trên. Chúng tôi lưu ý rằng sự quan trọng của những vấn đề đó có liên quan đặc biệt đến biểu diễn số và chỉ ra nhiều tài liệu quan trọng về chủ đề này. Trong dạng đầy đủ nhất của nó, như với sản phẩm phần mềm thương mại, quá trình phát triển phần mềm bao gồm nhiều giai đoạn. Pha thiết kế nhận thức thiết lập các đặc tính hoạt động và hàm cơ bản, sau đó một thuật giải sẽ nghiên cứu.......hạn chế những công nghệ có thể thực hiện được. Tiếp theo, pha mã hoá tạo ra......đầu tiên... bộ phần mềm. Trong pha chạy thử và duyệt lại, những thiếu sót về kỹ thuật sẽ được sửa chữa và những ý tưởng mới sẽ được hợp nhất vào chương trình. Sự cung cấp tài liệu người sử dụng miêu tả cách thức điều khiển hệ thống và sự cung cấp tài liệu công nghệ giải thích cấu trúc vật lý và logic của nó. Cuối cùng, phần mềm được phát hành và hỗ trợ trên thị trường. Hoạt động sau cùng bao gồm hướng dẫn khách hàng, hỗ trợ công nghệ và tiếp tục bảo trì phần mềm. (những dấu .... là do photo bị mờ không đọc được) Một dự án ứng dụng khác một dự án phát triển ở chỗ một cái sử dụng phần cứng hiện tại và một cái sử dụng phần mềm để giải quyết bài toán riêng. Điều này bắt đầu với sự lựa chọn nền phần cứng và bộ phần mềm được sử dụng. Tiếp theo pha thiết kế nhận thức là sự tập hợp một bộ ảnh dùng để phát triển và kiểm tra. Theo sau sự phát triển thuật giải thực sự là việc thực hiện kiểm tra và sau đó đưa công nghệ đi vào sử dụng. Điều này phải bao gồm việc chứng minh và công bố công nghệ, hướng dẫn học tập nghiên cứu trong khoảng thời gian hạn chế, hoặc cài đặt hệ thống trong vài hoạt động hướng vào sự sản xuất (production-oriented). 4.2 CÁC HỆ THỐNG XỬ LÝ ẢNH Các hệ thống máy tính được sử dụng phổ biến nhất cho xử lý ảnh được chia thành bốn hạng: (1) Apple Macintosh, với phần mềm hệ điều hành sẵn có của nó và giao diện người sử dụng; (2) các máy tính tương thích IBM-phần cứng, sử dụng hệ điều hành đĩa (DOS, PS/2,...) và Microsoft WindowsTM thường xuyên cũng như IBM OS/2TM; (3) các trạm làm việc đồ hoạ, điển hình là sử dụng hệ điều hành UNIX và môi trường XWINDOWS; (4) các hệ thống máy tính lớn (mainframe), với tài nguyên rộng lớn dùng chung (share) cho nhiều người sử dụng (multiple users) định vị tại các trạm làm việc từ xa. Các nhóm hệ thống gần nhau thường dùng chung tài nguyên và dữ liệu thông qua mạng cục bộ (Local Area Network-LAN). Chúng cũng thường xuyên truy cập đến mạng diện rộng (WAN). 47
- 4.2.1 Khuôn dạng file dữ liệu ảnh Với tư cách một phạm vi hoạt động, nói chung xử lý ảnh số tạo ra một lượng lớn các file dữ liệu lớn có liên quan chứa ảnh số. Những file này phải được lưu trữ và chúng luôn cần được trao đổi giữa những người sử dụng và những hệ thống khác nhau. Bắt buộc phải có vài khuôn dạng tiêu chuẩn cho việc lưu trữ và truyền các file ảnh số. Nhiều dạng file ảnh số đã được định nghĩa và sử dụng. Một vài dạng đã được sử dụng khá rộng rãi trở thành tiêu chuẩn phổ biến (de facto) không ít thì nhiều. (Xem ví dụ bảng 4-1) Hầu hết những chương trình xử lý ảnh thương mại có sẵn có thể đọc và ghi vài khuôn dạng file ảnh phổ biến. Các chương trình khác hiện có hoàn toàn có thể đọc và hiển thị ảnh lưu trữ dưới nhiều dạng file khác nhau và chuyển đổi chúng từ dạng này sang dạng khác. Các chương trình đó tự động hiểu dạng file đầu vào đã định, từ phần mở rộng tên file hoặc từ thông tin định danh trong chính bản thân file. Khi lưu lại ảnh hiển thị vào một file, người sử dụng có thể chỉ rõ khuôn dạng file mong muốn. BẢNG 4-1 KHUÔN DẠNG FILE DỮ LIỆU ẢNH Tên Kiểu Cách sử dụng Tagged image format *.TIF DOS, UNIX and Macintosh images Encapsulated PostScript *.EPS Publishing industry format Graphical interchange format *.GIF CompuServe graphics format Bit-mapped format *.BMP Microsoft Windows format Presentation manager *.BMP IBM OS/2 Bit-mapped format Macintosh *.PICT Apple Macintosh images Đa số các khuôn dạng file ảnh lưu trữ nhãn chú thích thêm vào dữ liệu ảnh. Chú thích này có thể là dữ liệu về sự tạo ra và khuôn dạng ảnh, cũng như chú thích của người sử dụng. Thông thường, các thiết bị hiển thị đơn sắc dùng mạch chuyển đổi số-tương tự (DAC) 8 bit để tạo ra tín hiệu video điều khiển độ sáng các điểm ảnh hiển thị trên màn hình. Thiết bị này có khả năng cung cấp 256 trạng thái xám. Các thiết bị hiển thị màu sử dụng các bộ chuyển đổi số-tương tự (DAC) 8 bit tạo ra bao tín hiệu video điều khiển các thành phần độ sáng đỏ (red), lục (green), lam (blue) của ảnh hiển thị. Vì thế, chúng có khả năng hiển thị 224, tức là hơn 16 triệu màu khác nhau. Do sự thiếu hoàn chỉnh thông thường trong các ống hiển thị và sự hạn chế của mắt người nên số lượng màu có thể nhận thấy rõ ít đi một cách đáng kể. Ảnh số không những xuất hiện ở khuôn dạng đơn sắc và màu, mà còn ở các mức độ khác nhau của độ phân giải đo sáng (photometric resolution) (số màu hoặc trạng thái xám). Với ảnh đơn sắc, số lượng trạng thái xám trong thang xám (gray scale) phổ biến nhất là 2, 16 hoặc 256 ứng với 1, 4 hoặc 8 bit/điểm ảnh. Những độ phân giải riêng biêt này dễ dàng được đóng gói thành những byte 8 bit trong bộ nhớ và các file trên đĩa. Những độ phân giải khác nhau cũng được sử dụng trong các ứng dụng nào đó. Bảng màu (palette) là một bảng tra cứu (look-up) liên kết mỗi giá trị điểm ảnh trong ảnh với màu hiển thị tương ứng. Một ảnh màu 4 bit sử dụng 16 màu cụ thể chọn trong bảng 16 triệu màu của nó để hiển thị. Đối với ảnh màu, số lượng màu quy định được biểu thị bởi các giá trị điểm ảnh khác nhau. Một ảnh màu 4 bit chỉ có thể hiện ra 16 màu phân biệt trên thiết bị hiển thị. Một bảng màu định nghĩa phép ánh xạ từ 16 giá trị điểm ảnh có thể tồn tại sang số lượng màu hiển thị lớn nhất. Sự lựa chọn 16 màu cụ thể là ý muốn của người lập trình và thường bị người sử dụng bỏ qua. Ảnh màu 8 bit được hiển thị với 256 màu riêng biệt và ảnh màu 24 bit có phạm vi thể hiện 16 triệu màu. Bảng màu chỉ rõ phép 48
- ánh xạ đối với một ảnh màu cụ thể thông thường được bao hàm trong file dữ liệu ảnh và nó điều khiển thiết bị hiển thị khi ảnh được hiển thị hay in ra. 4.3 GIAO DIỆN NGƯỜI SỬ DỤNG Thời kỳ đầu của máy tính, giao diện chủ yếu giữa người sử dụng với hệ thống là phần mềm hệ điều hành của nhà sản xuất. Mặc dù đã có tính mềm dẻo, nhưng những bộ sản phẩm này rõ ràng là cồng kềnh trong sử dụng hàng ngày. Gần đây hơn, xu hướng ngày càng tiến tới việc sản xuất giao diện phần mềm khá thân thiện với người sử dụng. Điều này tạo cho thao tác viên (operator) một môi trường tiện lợi và thoải mái để phát triển và sử dụng phần mềm xử lý ảnh số. Một giao diện người sử dụng như trên đòi hỏi các công cụ thuận tiện có sẵn, với chi phí tối thiểu. Các bộ phần mềm xử lý ảnh số hiện đại đặt khả năng xử lý và tính mềm dẻo vào tay người sử dụng một cách nhanh và dễ dàng. Thiết kế của chúng phục vụ cho trực giác của người sử dụng và điều này làm cho chúng dễ dàng để học và sử dụng. 4.3.1 Bộ thông dịch dòng lệnh (Command-Line Interpreter) Kiểu giao diện người sử dụng cũ nhất và đơn giản nhất là bộ thông dịch dòng lệnh (Hình 4-1). Sử dụng ngôn ngữ nguyên văn (textual language) dành riêng, yêu cầu người sử dụng phải biết các tuỳ chọn có sẵn, từ bộ nhớ hay tài liệu mở trên bàn. Nó đưa ra trước mắt người sử dụng một dấu nhắc (prompting character) trên màn hình báo hiệu rằng nó sẵn sàng xuất phát, nhưng nó không cung cấp sự hỗ trợ vấn đề gì mà có thể thực hiện được. Điều này yêu cầu độ tin cậy cao vào tài liệu được viết, đặc biệt trong giai đoạn học (learning phase). Tình hình được cải thiện đáng kể bằng cách sử dụng những file batch hay script, định rõ một loạt các bước xử lý và có thể được gọi bằng một lệnh đơn. Tập các file script phong phú có thể làm cho một bộ thông dịch dòng lệnh giải quyết dễ dàng. HÌNH 4-1 Hình 4-1 Giao diện bộ thông dịch dòng lệnh 4.3.2 Giao diện điều khiển bằng trình đơn (Menu-Driven Interface) Thế hệ thứ hai, giao diện điều khiển bằng trình đơn, đưa ra một danh sách các chọn lựa trên màn hình, sự lựa chọn có thể được hoàn thành bằng một hoặc hai phím bấm (Hình 4-2). Điều này giảm bớt việc phải ghi nhớ và phụ thuộc của thao tác viên vào tài liệu được viết rất nhiều, cũng như đòi hỏi sự cố gắng để đưa một quá trình chi tiết vào hoạt động. Trong sự hiện diện tiến bộ hơn của mình, giao diện người sử dụng điều khiển bằng trình đơn hoạt động đáp ứng lại thiết bị con trỏ đồ hoạ (graphic pointer device) (mouse, trackball,...). Đây là giao diện trỏ và kích (point-and-click), người sử dụng 49
- có thể di chuyển con trỏ đến khu vực đã gán nhãn thích hợp và nhấn một nút trên thiết bị. Người sử dụng cũng có thể kéo xuống (pull down) một trong nhiều trình đơn (menu) từ thanh trình đơn trên đỉnh màn hình hiển thị nếu cần thiết, theo cách đó sẽ làm giảm bớt sự lộn xộn trên màn hình, sau đó người sử dụng kích vào một chọn lựa tuỳ ý và trình đơn xuất hiện. Các trình đơn có thể hiện hữu theo cấu trúc phân cấp. Việc chọn một mục trên trình đơn làm xuất hiện một trình đơn con nhiều lựa chọn cụ thể hơn. Mỗi trình đơn hay mục trên trình đơn có thể cũng kết hợp với một thông báo trợ giúp (help message) giải thích các tuỳ chọn và cách sử dụng của nó. Điều này cũng có thể xuất hiện tại những nơi mà thao tác viên yêu cầu trên màn hình. HÌNH 4-2 Hình 4-2 Giao diện điều khiển bằng trình đơn trong môi trường cửa sổ 4.3.3 Giao diện đồ hoạ (Graphical User Interface) Thế hệ thứ ba là giao diện người sử dụng bằng đồ hoạ (GUI- phát âm là “gooey”). Thao tác viên điều khiển một phần hệ thống theo ngôn ngữ trực quan (visual language) thay vì ngôn ngữ nguyên văn đơn thuần như với bộ thông dịch dòng lệnh. GUI biểu diễn các tuỳ chọn cho sẵn không phải bằng văn bản, như trong một trình đơn, mà bằng các biểu tượng đồ hoạ hiển thị trên màn hình. Những biểu tượng (icon) này không những biểu thị các quá trình, mà còn biểu diễn dữ liệu (ví dụ như ảnh số) và các thiết bị phần cứng (ổ đĩa, máy in,...). Với sự thực hiện GUI đầy đủ, ta có thể khởi đầu một công việc - ví dụ, in một ảnh đã lưu trữ - bằng kỹ thuật kéo và thả (drag and drop). Sử dụng thiết bị con trỏ, thao tác viên có thể chọn ra biểu tượng biểu diễn ảnh, di chuyển nó sang biểu tượng khác biểu diễn máy in và nhả nó ra, và quá trình in bắt đầu. Điều này không chỉ nhanh hơn việc gõ dòng lệnh mà còn thú vị hơn. 4.3.4 Giao diện luồng dữ liệu (Data Flow Interface) Một kiểu GUI khác sử dụng mạng (network), biểu đồ luồng dữ liệu (data-flow diagram) bằng đồ hoạ, diễn đạt bằng hình tượng (symbology) (Hình 4-3). Ở đây, ngôn ngữ trực quan hầu như được sử dụng riêng biệt. Ta lại có một trình đơn các biểu tượng (các nét chạm-glyphs) biểu diễn các thiết bị, dữ liệu và quá trình sẵn sàng để sử dụng. Tuy nhiên, trong trường hợp này, bằng cách dùng con trỏ kéo các biểu tượng, ta có thể tạo ra một lưu đồ (flowchart) miêu tả dãy các bước xử lý đã định trên màn hình. Mỗi biểu tượng có một hoặc nhiều đường (pad) vào và/hoặc ra (các điểm kết nối) dành riêng. Người sử dụng định rõ luồng xử lý bằng cách liên kết các đường với các dòng kẻ sử dụng thiết bị con trỏ. 50
- HÌNH 4-2 Hình 4-3 Ví dụ về biểu đồ luồng dữ liệu GUI Mỗi biểu tượng cũng có các đường điều khiển, khi được chọn bằng con trỏ, mà bắt đầu thực hiện quá trình hoặc khiến các trình đơn xuất hiện bất kỳ, do đó cho phép người sử dụng định nghĩa các chi tiết của quá trình. Mỗi biểu tượng biểu thị một chỉ báo (indicator) trạng thái cho biết (1) nó được định nghĩa đầy đủ hay không, (2) sẵn sàng hoạt động hay không, (3) đã thực sự hoàn thành các hoạt động của nó chưa. 4.3.5 Cửa sổ Trong những ngày đầu của xử lý ảnh, người sử dụng có cơ sở để nhận ra rằng nhiều màn hình hiển thị đã tăng khả năng sử dụng của nó trong hệ thống lên rất nhiều. Ví dụ, thích hợp để sử dụng các cách hiển thị khác nhau đối với giao diện người sử dụng và đối với hiển thị ảnh. Một sự lựa chọn hiện nay (và rẻ hơn) là sử dụng thiết bị hiển thị khuôn dạng đơn và lớn cho các hàm khác nhau cùng một lúc. Môi trường hướng cửa sổ (Window-oriented environment) là một bộ phần mềm sử dụng màn hình hiển thị có hiệu quả để trình bày những đối tượng độc lập khác nhau cùng một lúc. Người sử dụng có thể mở (chẳng hạn, thiết lập hay định nghĩa) nhiều cửa sổ hiển thị khác nhau và sử dụng mỗi cửa sổ cho một mục đích hiển thị khác nhau, ngay cả khi ta sử dụng nhiều àn hình hiển thị. Mỗi cửa sổ có thể được định vị và định kích thước lại trên màn hình, điển hình là dùng thiết bị con trỏ kéo những đường biên của nó. Ở đây các cửa sổ chồng lên nhsu, một cửa sổ (cửa sổ hoạt động) che khuất một phần hay toàn bộ cửa sổ hoặc các cửa sổ “ở dưới” nó, như sự chồng đè lên nhau của các ảnh trên màn hình nền. Xu hướng thiết kế giao diện người sử dụng là chú ý nhiều vào ngôn ngữ trực quan, trả giá bằng ngôn ngữ nguyên văn. Cảm giác với giao diện trực quan là dễ dàng hơn cho người bắt đầu học và nhanh hơn cho chuyên gia sử dụng so với việc đánh máy văn bản từ bàn phím. Đầu vào bằng tiếng nói cũng là vấn đề thêm vào hữu ích với chuột và bàn phím. Tiếng nói tổng hợp cho phép hệ thống trả lời thao tác viên đúng như vậy. Giao diện bằng lời như trên đặc biệt hữu dụng khi thao tác viên phân chia sự chú ý của mình cho nhiều công việc khác. Trong vài trường hợp, chuỗi các tín hiệu video số hoá có thể cung cấp sự trợ giúp trực tuyến (on-line) có giá trị khi cần thiết. 4.4 QUÁ TRÌNH PHÁT TRIỂN PHẦN MỀM Trong những ngày đầu của lập trình máy tính nói chung và xử lý ảnh số nói riêng, quá trình phát triển phần mềm, theo cách nói bây giờ, là không có cấu trúc (unstructured). Những người lập trình máy tính không chỉ hiếm, giống như những kiểu người tiên phong khác, mà còn có tính chất chủ nghĩa cá nhân. Có lẽ chỉ với một khái niệm mơ hồ về công việc mà một phần mềm mới được yêu cầu làm, người lập trình đã có thể bắt tay vào viết mã lệnh, tổng hợp một vấn đề phức tạp từ những phần đơn giản hơh trong quá trình. Sau đó, toàn bộ thiết kế dược phát triển song song với việc thực hiện. Những sự giải quyết thiết kế chủ yếu được thực hiện theo cách từ đầu đến đuôi. Thông thường các mô đun (module) được phát triển từ dưới lên, với các chương trình con (routine) cơ bản nhất được viết đầu tiên và 51
- tiếp theo các chương trình con mức cao hơn dựa vào những chương trình con trước đó, những người lập trình ban đầu đã khai thác một cách sáng tạo sự phong phú của ngôn ngữ lập trình cấp cao đương thời để viết mã lệnh nhanh, cô đọng và bản chất là không thể giải mã được. Khoảng năm 1970, nhiều vấn đề với cách tiếp cận này đã trở thành hiên nhiên. Đầu tiên, sự phức tạp của các dự án phần mềm tiến đến mức mà người lập trình khó lòng giữ tất cả các khía cạnh của chương trình cùng lúc trong đầu. Nghiên cứu tâm lý học đưa ra giả thiết là con người thật là khó chịu khi cố gắng giữ dấu vết của nhiều hơn năm đến chín mẩu thông tin cùng một lúc. Hạn chế này lấy đi mất một phần lớn giá cả và ngân sách của các dự án phát triển phần mềm lớn lặp đi lặp lại nhiều lần. Thứ hai, với các dự án bao gồm các nhóm những nhà lập trình, sự phối hợp kết quả của sự cố gắng thành một vấn đề trọng đại. Các mô đun được viết bởi những cá nhân khác nhau sẽ không thành công trong việc làm cho khớp vào với nhau một cách trôi chảy. Thứ ba, như khi có sự thay đổi nhân viên, nó trở nên khá tốn phí đối với những người lập trình mới để giải mã (decipher) mã nguồn hiện tại trong tình trạng thiếu một vài cấu trúc agreed-upon phổ biến, đặc biệt khi thiếu tài liệu đi kèm. Ví dụ, theo bố trí của một trường đại học, sự ra đi của một sinh viên hay một cán bộ lập trình có thể làm cho tất cả phần mềm mà anh ta hay cô ta đã phát triển trong khi làm việc trên các dự án nghiên cứu không sử dụng. Các dự án phát triển phần mềm thương mại đòi hỏi sự tác động qua lại lẫn nhau đáng kể giữa nhiều các nhân để chắc chắn rằng sản phẩm cuối cùng thoả mãn tất cả các yêu cầu trên (thường cạnh tranh). Hình 4-4 là ví dụ về môt lưu đò sử dụng trong môt dự án phát triển phần mềm thương mại. Các bước quan trọng vòng phát triển phần mềm được liệt kê trong bảng 4-2. Những bước này có thể được thực hiện một cách tuần tự, bằng cách gối chồng lên nhau, hay lặp. Theo định nghĩa, phân tích là quá trình nghiên cứu vấn đề và chỉ ra những đặc tính hoạt động của bài giải. Kết quả cho ta là một đặc tả hàm (functional specification) phần mềm. Thiết kế là thực hiện đặc tả này và thêm những chi tiết yêu cầu cho việc thực hiện trên một nền phần cứng riêng biệt. Lập trình, dĩ nhiên là viết, kiểm tra, gỡ rối và cung cấp tài liệu các chương trình máy tính. BẢNG 4-2 QUÁ TRÌNH PHÁT TRIỂN PHẦN MỀM 1. Phân tích yêu cầu - Requirements analysis 2. Thiết kế sơ bộ - Preliminary design 3. Mẫu - Prototyping (if required) 4. Thiết kế chi tiết - Detailed design 5. Thực hiện - Implementation (coding) 6. Kiểm tra - Testing 7. Bảo trì - Maintenance HÌNH 4-4 52
- Hình 4-4 Ví dụ về một lưu đồ phát triển phần mềm Mặc dù cách tiếp cận này có thể nảy sinh sự phức tạp quá mức cần thiết, nhưng kinh nghiệm cho thấy việc thực hiện một công việc lần đầu tiên rẻ hơn là sử dụng thêm thời gian cho việc thay đổi và gỡ rối một chương trình do nó đã được thực hiện tồi tệ ngay từ đầu. 4.4.1 Quá trình hoạt động của chương trình Một chương trình ứng dụng có thể hoạt động ở một trong ba chế độ, tuỳ thuộc vào vai trò mà nó thực hiện trong quá trình tính toán. Trong chế độ lô (batch mode), chương trình được đặt vào một hàng đợi (queue) và được thi hành bất cứ lúc nào máy tính giải quyết xong những công việc trước đó. Mặc dù các câu lệnh phải được thực hiện tuần tự, không có sự khác nhau mấy giữa những sự thực hiện các lệnh dù nó diễn ra hàng nano giây hay hàng phút. Vài chương trình xử lý ảnh thuộc vào loại này. Một chương trình được điều khiển theo sự kiện (event-driven program) tham gia một vòng lặp sự kiện, chờ đợi sự kiện nào đó xảy ra. Bình thường, thao tác viên gây ra một hoạt động (nhấn phím, kích chuột,...) tạo thành một sự kiện. Chương trình liên tục thăm dò (poll) các thiết bị đầu vào, kiểm tra và nhận diện mỗi sự kiện khi nó xảy ra. Sau đó nó thực hiện chương trình con thích hợp và trở về vòng lặp sự kiện. Bình thường các chương trình xử lý ảnh ảnh hưởng lẫn nhau thuộc loại này. Chương trình thời gian thực (real-time) điều khiển một quá trình đang xảy ra, ví dụ như các hoạt động sản xuất. Bản thân thời gian đóng một vai trò quan trọng trong các quá trình tính toán. Thường thường, chương trình điều khiển đầu ra của quá trình trong khi điều chỉnh các tham số điều khiển quá trình. Điều này cũng có thể bao hàm trong xử lý ảnh. 4.4.2 Thiết kế từ trên xuống (Top-Down) Vào đầu những năm 1970, những khái niệm lập trình có cấu trúc (structured progamming) và thiết kế trên xuống (top-down design) xuất hiện để giải quyết các bài toán do lập trình không có cấu trúc tạo ra. Thiết kế trên xuống đầu tiên cần phải viết và gỡ rối phần mềm mức cao nhất (giao diện người sử dụng) và sau đó thêm dần các chương trình con mức thấp hơn, những chương trình con điều khiển phần cứng thường được viết sau cùng. Kiểu thiết kế này tương phản với thiết kế dưới lên (bottom-up), ở trong ấy người ta viết những chương trình con đơn giản nhất đầu tiên và xây dựng dần lên từ chúng, đôi khi nhận ra rằng các chương trình con mức thấp hơn bỏ sót một hàm cần thiết. Thiết kế trên xuống có hai lợi thế quan trọng. Một lợi thế có liên quan đến giao diện giữa các mô đun. Mức đỉnh được thiết kế trực tiếp từ đặc tả chức năng của hệ thống. Mỗi giao diện giữa các mô đun được thực hiện bởi các gốc (stub). Lợi thế thứ hai là có thể giải thích được từng phần của hệ thống trong quá trình phát triển. Giao diện người sử dụng có thể được đưa ra và ước lượng từ lúc đầu, đem lại cho người sử dụng khả năng xem trước sự việc. Những gốc (stub) đại diện cho những chương trình con mức thấp hơn chưa viết. Dần dần thay thế các gốc bằng các chương trình con, từ trên xuống, như dự án trình bày. 4.4.3 Hướng phát triển có cấu trúc Cách tiếp cận có cấu trúc đối với sự phát triển phần mềm trở nên nổi bật vào những năm 1970. Đó là một sự cố gắng để làm cho quá trình hiệu quả hơn bằng cách chính thức hoá (formalizing) nó, tác động lên nó và sử dụng các công cụ thiết kế phục vụ cho việc giải quyết trước các vấn đề rắc rối khác của quá trình. Phát triển có cấu trúc chủ yếu phân tích vấn đề theo những giai đoạn chức năng, rất phù hợp cho các chương trình chế độ lô (batch mode). 53
- 4.4.3.1 Phân tích có cấu trúc Phép phân tích có cấu trúc phân tích vấn đề mà đã được giải quyết theo những giai đoạn chức năng. Đưa đến kết quả là đặc tả có cấu trúc (structured specification), bao gồm (1) các biểu đồ luồng dữ liệu (data flow diagrams-DFDs) trình bày sự phân tích toàn bộ chức năng vào trong các quá trình, luồng dữ liệu và các giao diện giữa các quá trình; (2) từ điển dữ liệu (data dictionary) cung cấp tài liệu về dữ liệu và giao diện trong các DFD; và (3) diễn tả sự biến đổi (transform description) cung cấp tài liệu về chức năng của mõi quá trình trên DFD. Đặc tả có cấu trúc đưa ra những thành phần cấu trúc hệ thống khác nhau và thông tin trao đổi như thế nào và biến đổi bằng cách nào, giữa các thành phần. 4.4.3.2 Thiết kế có cấu trúc Mục đích của thiết kế có cấu trúc là một phương pháp luận có tổ chức sao cho có thể phân biệt được giữa các thiết kế tốt và xấu, đi đến một giải pháp tối ưu. Đó là sự tập hợp những chiến lược và kỹ thuật, đáp ứng những mục tiêu và ràng buộc kỹ thuật phổ biến cho môi trường khoa học và thương mại. Thiết kế có cấu trúc phát triển một phác thảo bao gồm những thành phần hộp đen (black-box) mà chức năng của nó được xác định rõ, nhưng những công việc bên trong thì không. Nó chia sẻ nhiều nguyên tắc công nghệ được sử dụng để phát triển những biểu đồ tổ chức với các công ty. 4.4.3.3 Lập trình có cấu trúc Lập trình có cấu trúc thiết lập các kỹ thuật mã hoá tiêu chuẩn hoá và xoá bỏ một số lệnh nào đó của thói quen lập trình đơn giản khỏi những ngôn ngữ lập trình. Những chương trình có cấu trúc tuân theo lưu đồ được xây dựng từ tập giới hạn các hàm con lối vào đơn, lối ra đơn. Công việc lập trình sẽ trở thành sự cố gắng rèn luyện nhiều hơn, vận dụng các tiêu chuẩn một cách khôn ngoan và sáng tạo. Mã kết quả sẽ dễ đọc, kiểm tra, thay đổi, cung cấp tài liệu và gỡ rối hơn. Ngôn ngữ lập trình có cấu trúc, ví dụ như Pascal, Ada và C, ra đời để cạnh tranh với những ngôn ngữ không có cấu trúc như FORTRAN và BASIC. Ngôn ngữ có cấu trúc cung cấp những khả năng khuyến khích và hỗ trợ sự rèn luyện trí óc cho lập trình có cấu trúc và tránh xa những thói quen lập trình tầm thường. Hiện nay, những phiên bản gần đây nhất của những ngôn ngữ ra đời đầu tiên cũng kết hợp chặt chẽ một vài khái niệm về cấu trúc. Trong ngôn ngữ không có cấu trúc, chuỗi điều khiển (thread of control) tự do nhảy lung tung khắp nơi trong chương trình. Một ví dụ là lệnh tính toán GOTO trong FORTRAN. Điều khiển được chuyển đến một trong nhiều vị trí mã nguồn khác nhau, tuỳ thuộc vào giá trị biến được xác định tại thời điểm thực hiện lệnh. Việc đọc và hiểu danh sách chương trình con chứa các cấu trúc này có thể cực kỳ khó khăn - thậm chí ngay chính tác giả chương trình - nếu mã nguồn đã viết trước đây hơn 60 ngày. Trong ngôn ngữ có cấu trúc, luồng điều khiển bị cấu trúc đơn luồng (single- thread) hạn chế, mã và dữ liệu dễ dàng chia thành ngăn. Các chương trình con chỉ sử dụng các biến cục bộ (tạm thời) không thể tác động đến những phần khác của chương trình. 4.4.4 Phát triển hướng đối tượng (Object-Oriented Development) Sự phát triển phần mềm theo cách tiếp cận hướng đối tượng phân tích vấn đề theo các giai đoạn quan hệ dữ liệu. Một cách khái niệm, một chương trình được phân tích thành các đối tượng (object), mỗi đối tượng là một sự kết hợp dữ liệu có liên quan tới một khía cạnh riêng biệt của vấn đề và mã tương ứng sử dụng những dữ liệu đó để thực hiện một tập các chức năng hoàn toàn xác định. Dữ liệu và mã chương trình 54
- được đóng gói (encapsulate) thành một bộ khép kín (seamless package), những công việc bên trong bộ được che đậy không cho thế giới bên ngoài biết. Cách tiếp cận này rất phù hợp với những ứng dụng điều khiển theo sự kiện. Mỗi đối tượng hoạt động giống như một hộp đen (black box), thực hiện những chức năng đã được định nghĩa theo yêu cầu, nhưng có bộc lộ chút ít bề những công việc bên trong nó. Nó nhận một thông báo để hành động, khi đã hoàn thành nó cũng trả lời lại bằng một thông báo. Mỗi đối tượng là độc lập và quản lý chương trình điều khiển và luồng dữ liệu cùng một lúc, mặc dù nó đang hoạt động. Điều này làm cho chương trình có quá nhiều mô đun và tránh được tình trạng những thay đổi bên trong một chương trình con sẽ tạo ra kết quả không ngờ cho những phần chương trình khác. 4.4.4.1 Phân tích hướng đối tượng Phân tích hướng đối tượng của một vấn đề cho ta một danh sách các đối tượng sẽ cùng nhau giải quyết vấn đề. Danh sách này bao gồm một đặc tả dữ liệu (các thuộc tính) và các chức năng (các dịch vụ) của mỗi đối tượng. Phân tích hướng đối tượng được thực hiện mà không quan tâm đến phần cứng, hệ điều hành, hay các công cụ phần mềm sẽ được sử dụng để thực hiện. 4.4.4.2 Thiết kế hướng đối tượng Giai đoạn thiết kế hướng đối tượng vạch ra cách mà thiết kế logic sẽ được thực hiện từ những phân tích-đó là sự kết hợp giữa phần cứng, hệ điều hành và các công cụ phát triển phần mềm (chẳng hạn như bộ biên dịch,...). Thường thường, thay đổi đáng kể của bản thiết kế ban đầu đòi hỏi phải có căn cứ xác thực. 4.4.4.3 Lập trình hướng đối tượng Trong lập trình hướng đối tượng, người lập trình thường bắt đầu với một sườn ứng dụng (application framework). Đây là một chương trình có nhiều chức năng chung, phổ biến cho đa số các chương trình. Nó giống như một bộ khung để xây dựng một đơn vị trọn vẹn trên đó. Bình thường, sườn ứng dụng điều khiển vòng lặp sự kiện và phát hiện sự kiện. Sau đó người lập trình chỉ phải thêm các đối tượng được yêu cầu vào ứng dụng sắp đến. Mỗi đối tượng viết bằng dữ liệu và điều khiển chương trình đã được đóng gói thành một đơn vị độc lập, được bọc kín nhiều hay ít. Những đối tượng mới không cần thiết kế và viết từ đầu; chúng có thể kế thừa (inherit) những đối tượng đã tồn tại trước đó. Vì vậy, ví dụ một kiểu cửa sổ hiển thị đã tồn tại, nó cần được thay đổi để tạo thành kiểu cửa sổ hiển thị khác. 4.4.5 Các công cụ CASE Trong thực tiễn, lượng thời gian đáng kể của người lập trình tiêu tốn cho việc thực hiện công việc không sáng tạo (noncreative)-những công việc mà nói đúng ra là máy móc và không yêu cầu kinh nghiệm đầu vào sáng tạo. Các công cụ phần mềm xuất hiện để làm thay đổi phạm vi hoạt động của phần phát triển này hơn nữa. Chúng thường được gọi với cái tên những công cụ công nghệ phần mềm được máy tính trợ giúp (computer-aided software engineering-CASE). Chúng kế tục nhiều chức năng cung cấp tài liệu và kiểm tra lỗi. Tất nhiên, điều cần thiết cho một người lập trình hay người thiết kế phần mềm đóng góp thông tin quan hệ thiết kế (design-related) vào hệ thống khi bắt đầu, nhưng các chương trình biên dịch và định dạng thông tin theo những cách đặc biệt có thể khiến con người tránh được sự nỗ lực to lớn không cần thiết. Việc sử dụng các công cụ CASE có hiệu quả sẽ phụ thuộc vào sự cố gắng áp dụng qui tắc lập trình và thiết kế phần mềm, ví dụ kêt cả miêu tả những chỗ đầu (header) được chuẩn hoá, nơi bắt đầu mỗi mô đun mã. 55
- Một ví dụ về công cụ CASE là chương trình kết hợp thông tin đầu từ tất cả các mô đun mã nguồn để tạo thành một quyển tài liệu phần mềm. Những chương trình khác có thể đọc các file mã nguồn, biên dịch một ánh xạ liên kết những phần phụ thuộc và truyền tin giữa các mô đun. Trong quá khứ, thiết kế nhận thức được hoàn thành khi bắt đầu dự án, với nhiều chi tiết thiết kế điền vào bằng cách phát triển mã hoá. Xu hướng tiến tới hiện nay là tập trung vào toàn bộ sức lực thiết kế ngay khi bắt đầu dự án. Điều này có nghĩa là việc lập trình thực tế là quá trình máy móc trên quy mô lớn, hoạt động với tài liệu thiết kế hoàn toàn đặc biệt. Sự phân nhánh của xu hướng mới này gồm hai phần. Thứ nhất, những đội phát triển phần mềm có khuynh hướng chia nhỏ thành những người thiết kế và những người lập trình. Thứ hai, sự sinh mã thực tế có thể được các công cụ CASE thực hiện. Một người thiết kế phần mềm ngồi tại một trạm làm việc, có thể phát triển đặc tả đầy đủ một bộ phần mềm. Sau đó những công cụ CASE có thể sử dụng những đặc tả này để tạo ra cả mã nguồn (không có lỗi mã hoá) lẫn tài liệu kỹ thuật (dù không phải tài liệu người sử dụng). 4.4.6 Sự độc lập đối với nền phần cứng (Platform Indepedence) Sự phát triển của bộ phần mềm xử lý ảnh là một công việc tốn nhiều thời gian và tiền bạc. Có nhiều hệ thống máy tính khác nhau có thể dùng để xử lý ảnh số. Các nền phần cứng khác nhau có mối quan hệ thuận lợi và bất lợi đối với việc thực hiện và giá cả. Sự tiến bộ của phần cứng xảy ra nhanh chóng đến nỗi sự lỗi thời không có khoảng cách. Vì thế, câng tránh một phần hay toàn bộ việc viết lại phần mềm cho mỗi thiết bị ngoại vi hoặc nềm phần cứng mới. Xu hướng của các phương pháp phát triển phần mềm hiện nay, phần chủ yếu, là độc lập với phần cứng mà chúng chạy trên đó. Bộ công cụ cầm tay (portability tool kit) là giao diện phần mềm nằm giữa chương trình ứng dụng độc lập với nền phần cứng và hệ thống địa phương (hệ thống chạy những ứng dụng đó-native system) (Hình 4-5). Chương trình ứng dụng được viết theo những quy tắc tiêu chuẩn giống như bộ công cụ viết trên nền phần cứng. Bộ công cụ này cung cấp giao diện giữa chương trình ứng dụng và hệ điều hành của hệ thống địa phương, GUI và tài nguyên bộ nhớ. Nó biên dịch sự truyền thông tin giữa ứng dụng và hệ thống mà ứng dụng chạy trên đó. HÌNH 4-5 Hình 4-5 Cơ cấu phần mềm độc lập với nền phần cứng. Mỗi hệ thống cục bộ khác nhau (chẳng hạn, trạm làm việc UNIX, Macintosh,...) có một phiên bản của bộ công cụ cầm tay khác nhau, nhưng mỗi phiên bản đều quan tâm đến chương trình ứng dụng như nhau. Theo cách đó, một chương trình ứng dụng được phát triển trên một hệ thống cục bộ sẽ hoạt động (theo lý thuyết) mà không có 56
- sự thay đổi nào trên hệ thống cục bộ khác. Trong đa số các trường hợp, chỉ có sự hạn chế về mặt chức năng được yêu cầu sau khi chuyển một chương trình ứng dụng sang hệ thống cục bộ khác. Bộ công cụ cầm tay thiết kế tốt sẽ giúp người lập trình truy cập trực tiếp đến hầu hết, nếu không muốn nói là tất cả, các đặc điểm và tài nguyên của hệ thống cục bộ. Những đặc điểm đó không tồn tại trên hệ thống cục bộ, nhưng tồn tại trên hệ thống cục bộ khác trong thiết bị hỗ trợ, được bộ công cụ mô phỏng trong phần mềm. Một bộ công cụ cầm tay tốt, về cơ bản, sẽ cho phép người lập trình truy cập vào mọi đặc điểm sẵn có trên tất cả các hệ thống cục bộ được hỗ trợ và cả những đặc điểm thêm vào. Khi một chương trình độc lập với nền phần cứng chuyển sang hệ thống cục bộ khác, thì chức năng của nó vẫn không thay đổi. Tuy nhiên, “mắt và tay” của nó sẽ thuộc về “chủ mới” (hệ thống cục bộ mới) của nó. Chạy trên máy Macintosh, trông nó sẽ giống như là được viết cho máy này và cũng như vậy đối với các nền phần cứng khác. Lập trình độc lập với nền phần cứng khiến cho những người lập trình di chuyển nó giữa các nền dễ dàng hơn. Họ không phải tìm hiểu tập đặc tính và tài nguyên mới mỗi khi thay đổi, với điều kiện là phải sử dụng bộ công cụ cầm tay tương tự. 4.4.7 Cung cấp tài liệu phần mềm Tài liệu kèm theo sự phát triển và sử dụng bộ phần mềm xử lý ảnh chia thành năm loại. Đầu tiên là tài liệu thiết kế, nó định rõ bộ phần mềm dùng để làm gì. tiếp theo là tài liệu về mã phần mềm, bao gồm các thuật giải và các chi tiết cấu trúc mô đun. Thứ ba là tài liệu chỉ dẫn cho thao tác viên, nó có thể bao gồm những bài tập tự học cho người mới bắt đầu sử dụng. Thứ tư là tài liệu tham khảo, nó tổ chức những thông tin đặc biệt, súc tích, ít khi sử dụng của thao tác viên có kinh nghiệm. Thứ năm là trợ giúp trực tuyến, người sử dụng có thể gọi nó trên màn hình (thường trong một cửa sổ trợ giúp độc lập) trong khi chương trình vẫn đang chạy. Thỉnh thoảng, do hấp tấp mà sự cố gắng cung cấp tài liệu trở nên tồi tệ hơn trước khi hoàn thành và phát hành phần mềm. Cái giá phải trả, về thời gian và tiền bạc, cho tài liệu không tương xứng thường khá cao. Việc cố gắng giải mã quá trình hoạt động của phần mềm được cung cấp tài liệu tồi có thể gây bực dọc đến mức người mới sử dụng có thể bỏ dở giữa chừng trước khi trở nên thông thạo. Việc hoàn thiện một bản mã mà tài liệu cung cấp tồi gây tốn nhiều thời gian cũng giống như tiền bạc. Bộ phần mềm lý tưởng là bộ phần mềm với giao diện người sử dụng rõ ràng, đến nỗi ít khi cần sử dụng đến bộ tài liệu hoàn chỉnh và đầy đủ. Sau lời giới thiệu chương trình vắn tắt, người sử dụng chỉ yêu cầu sự hỗ trợ không thường xuyên từ trợ giúp trực tuyến và tài liệu tham khảo. 4.5 TỔNG KẾT NHỮNG ĐIỂM QUAN TRỌNG 1. Một phần mềm được thừa nhận phải là phần mềm có một giao diện người sử dụng tiện lợi, tài liệu tốt cung cấp cho người sử dụng, tính đầy đủ chức năng và sự chính xác cũng quan trọng. 2. Với đa số người sử dụng, giao diện người sử dụng đồ hoạ điều khiển bằng trình đơn dễ dàng để học và thao tác hơn giao diện bằng văn bản. 3. Chiều hướng phát triển giao diện người sử dụng là từ giao diện văn bản đến giao diện bằng lời nói và trực quan. 4. Một chương trình có thể chạy chế độ lô (batch mode), được điều khiển bằng sự kiện, hay hoạt động trong thời gian thực. 5. Phát triển phần mềm có cấu trúc là phân tích một vấn đề theo các giới hạn chức năng và làm nổi bật các giao diện và luồng dữ liệu giữa các thành phần. 57
- 6. Những chương trình có cấu trúc được xây dựng từ các hàm con đơn đầu vào, đơn đầu ra và tránh cấu trúc làm cho việc điều khiển chương trình trở nên khó khăn. 7. Phát triển hướng đối tượng đóng gói dữ liệu và các chức năng liên quan với mỗi thành phần hệ thống thành các đối tượng giao tiếp qua thông báo. 8. Lập trình độc lập với nền phần cứng cho phép phần mềm đã phát triển trên một kiểu hệ thống có thể di chuyển đến hệ thống kiểu khác một cách dễ dàng. BÀI TẬP 1. Phát triển một cấu trúc trình đơn hai mức cho chương trình được thiết kế để nhập vào, xử lý và xuất ra những ảnh thu được từ tàu vũ trụ. Chương trình phải có khả năng nhập vào những ảnh từ vệ tinh truyền xuống, Internet, modem và đĩa quang (laser), và xuất ảnh ra Internet, modem, đĩa quang và máy in. Đối với quá trình xử lý, chọn sáu quá trình ở phần 1 của sách. Giải thích số mức trình đơn tối ưu tiện lợi cho người sử dụng mà bạn chọn. 2. Trình bày một lưu đồ phát triển chương trình phần mềm xử lý ảnh mang tính thương mại cho kỹ nghệ kiểm tra chip tổ hợp. Chương trình sẽ tăng cường các ảnh hiển vi số hoá của chip và hiển thị các ảnh chip tốt đã lưu trữ để so sánh. DỰ ÁN 1. Thiết kế một giao diện người sử dụng dùng đồ hoạ (GUI) cho kiểu xử lý ảnh đặc biệt (ví dụ như ảnh thiên văn, y học, bản đồ) đầy đủ với trình đơn (menu), biểu tượng (icon),... 2. Thực hiện một mẫu (không phải hàm) giao diện người sử dụng đồ hoạ cho một kiểu xử lý ảnh đặc biệt và nhờ những người có năng lực duyệt lại. 3. Sử dụng một chương trình đồ hoạ, tạo bảng 16 màu thích hợp, dùng nó để tô màu một dòng kẻ số hoá. Cung cấp bảng màu, giữ nguyên màu sắc, độ bão hoà và cường độ của mỗi màu sử dụng trong ảnh. 4. Chuẩn bị bản phác thảo bộ tài liệu kỹ thuật chi tiết cho một bộ phần mềm có sẵn. 5. Chuẩn bị bản phác thảo bộ tài liệu người sử dụng chi tiết cho một bộ phần mềm có sẵn. 6. Viết một chương trình đọc ảnh đã lưu trong một dạng file, hiển thị và lưu chúng sang dạng file khác. 58
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Bài giảng Xử lý ảnh - PGS.TS. Đỗ Năng Toàn
113 p | 443 | 84
-
Bài giảng Xử lý ảnh - Đại học Hàng hải Việt Nam
70 p | 259 | 41
-
Bài giảng Xử lý ảnh số: Chương 7 - TS. Ngô Quốc Việt
71 p | 186 | 32
-
Bài giảng Xử lý ảnh số: Chương 1 - TS. Ngô Quốc Việt
43 p | 185 | 32
-
Bài giảng Xử lý ảnh số: Chương 2 - TS. Ngô Quốc Việt
60 p | 205 | 30
-
Bài giảng Xử lý ảnh số: Phân tích ảnh (Phân vùng ảnh) - Nguyễn Linh Giang
29 p | 166 | 25
-
Bài giảng Xử lý ảnh số: Chương 3 - TS. Ngô Quốc Việt
36 p | 144 | 25
-
Bài giảng Xử lý ảnh số: Chương 4 - TS. Ngô Quốc Việt
24 p | 165 | 23
-
Bài giảng Xử lý ảnh số: Giới thiệu - TS. Ngô Quốc Việt
8 p | 136 | 16
-
Bài giảng Xử lý ảnh: Chương 3 - Hoàng Văn Hiệp (p1)
103 p | 91 | 9
-
Bài giảng Xử lý ảnh số: Giới thiệu – ThS. Võ Quang Hoàng Khang
8 p | 144 | 8
-
Bài giảng Xử lý ảnh: Chương 4 - Nguyễn Thị Hoàng Lan
6 p | 57 | 7
-
Bài giảng Xử lý ảnh số: Phân tích ảnh (Xử lý ảnh nhị phân) - Nguyễn Linh Giang
16 p | 115 | 7
-
Bài giảng Xử lý ảnh: Chương 1 - Hoàng Văn Hiệp
14 p | 128 | 6
-
Bài giảng Xử lý ảnh số: Phân tích ảnh (Xử lý ảnh đường biên) - Nguyễn Linh Giang
33 p | 94 | 6
-
Bài giảng Xử lý ảnh: Chương 1 - Nguyễn Thị Hoàng Lan
13 p | 82 | 6
-
Bài giảng Xử lý ảnh số (Chương trình dành cho kỹ sư CNTT): Xử lý ảnh nhị phân - Nguyễn Linh Giang
16 p | 79 | 5
-
Bài giảng Xử lý ảnh: Chương 2 - Nguyễn Linh Giang
25 p | 85 | 3
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn