PDA

View Full Version : Xin hỏi về xử lý ảnh số viết bằng C#



nhanhnt
16-06-2009, 13:35
Bạn nào có code bài xử lý ảnh " Trích chọn và hòa hợp đặc trưng ảnh " thì post lên cho mình tham khảo được không. Mong các bạn giúp đỡ

hnb1988
23-09-2009, 00:02
Ok, mình cũng đang học về môn này, nhưng chưa rành lắm. Bạn có thể tham khảo thêm bài viết này ha:


* Đọc ảnh trong C#:

Dùng 1 đối tượng của lớp Bitmap để tạo mới 1 ảnh( mới hoàn toàn hay đọc mới từ file).
VD:
Bitmap bm = new Bitmap("C:\Pictures\abc.jpg");
// lệnh trên khai báo 1 biến bm, là 1 ảnh lấy từ C:\Pictures\abc.jpg

* In ảnh lên form:

Đọc được vào biến rồi, giờ phải in ra để mọi người cùng thấy đúng không? Dùng phương thức DrawImage để hiện ảnh lên
Ví dụ: Hiện ảnh lên form chính
Graphics gr = CreateGraphics();// Khởi tạo đồ hoạ trên form chính
gr.DrawImage(bm,0,0);
gr.Dispose()// Giải phóng biến graphics

Các tham số của DrawImage là:
bm: ảnh cần đưa ra màn hình
0,0 : toạ độ góc trên bên trái của ảnh

* Truy xuất và thay đổi từng pixel ảnh:

**Cấu trúc file ảnh:
Là 1 ma trận 2 chiều các pixel, ảnh thông thường là ảnh 24 bít, tức là mỗi pixel 24 bits= 3 bytes. Chúng ta tưởng tượng như sau: pixel đầu tiên của ảnh chiếm 3 byte đầu (0,1,2); pixel thứ 2 chiếm 3 byte tiếp (3,4,5); cứ như thế...
Để biết ảnh bm có kích thước bao nhiêu, C# cung cấp 2 thuộc tính:
bm.Width: số pixel trên 1 hàng(độ rộng)
bm.Height: số hàng(độ cao)
Như vậy, mỗi hàng của bức ảnh sẽ dùng hết bm.Width*3 bytes để lưu thông tin (do mỗi pixel 3 byte)
Tuy nhiên khi lưu vào máy, thì mỗi hàng của ảnh phải dùng nhiều hơn số byte đó để lưu, vì mục đích lưu cả thông tin của biên thì phải( cái này sẽ xem thêm).
Để biết thực sự số byte này là bao nhiêu, đầu tiên phải chuyển bm sang 1 lớp đệm, lớp BitmapData
Ví du:
Rectangle rec = new Rectangle(0,0,bm.Width,bm.Height);
BitmapData bmData = bm.LockBits(rec, ImageLockMode.ReadWrite, PixelFormat.24bitrgp);

Câu lệnh đầu tiên khai báo 1 hình chữ nhật rec, chính là kích thước của ảnh bm, và dùng làm tham số cho câu lệnh phía dưới.
Phương thức LockBits sẽ chuyển từ 1 ảnh, sang 1 vùng nhớ (bmData). Trên ảnh bm, ta chỉ có thể xem nó, chứ không thể chỉnh sử pixel. Muốn sửa, phải chuyển nó sang lớp BitmapData, trên đó có các thứ cần thiết để can thiệp vào từng điểm ảnh.

Bây giờ, bmData sẽ "trả công" cho ta bằng cách cung cấp cho ta 2 thuộc tính quan trọng:
- bmData.Stride: số byte thực sự mà máy tính lưu trũ mỗi hàng của ảnh. Quan trọng, vì nếu ta nghĩ ảnh kích thứơc 5x5, thì lưu trên đĩa 5x3=15 byte 1 hàng, nhưng nếu stride=16, thì khi ta muốn xuống dòng thứ 2 đễr xử lý tiếp, ta truy xuất vào byte thứ 16, thì thực tế ta lại truy xuất vào cái rìa của dòng 1.
- bmData.Scan0: chú ý là số 0, không phải chữ O.
Cái này chỉ ra địa chỉ pixel đầu tiên của ảnh mà bmData quản lý. Muốn thay đổi từng pixel ta phải biết cái này, rồi dùng con trỏ trỏ đến địa chỉ đó, thay đổi, sau đó dịch con trỏ lên 1 đơn vị, tiếp tục thay đổi tiếp. Tư tưởng là vậy.

** Ghép mấy thứ loằng ngoằng trên để xử lý 1 bức ảnh xem nào:

Đặt ra 1 ví dụ: đọc 1 bức ảnh và hiện lên form, khi người dùng nhấn vào 1 nút trên form, biến bức ảnh đó thành toàn màu trắng.

Các bước đọc ảnh và hiển thị đã nói ở trên. Ở đây ta chỉ quan tâm đến việc thay tất cả các pixel của ảnh thành pixel màu trắng. Chú ý màu trắng là cả 3 byte của nó đều bằng 255.

BitmapData bmData = bm.LockBits(rec, ImageLockMode.ReadWrite, PixelFormat.24bitrgp);
int stride = bmData.Stride;
int nOffset = stride - bm.Width*3;
//nOffset chính là cái rìa của bức ảnh, khi con trỏ xử lý đến pixel cuối cùng của hàng, thì muốn xuống //hàng kế tiếp, ta phải bỏ qua cái rìa này bằng cách cộng thêm địa chỉ con trỏ với nOffset

byte *p = (byte*)bmData.Scan0;
//p sẽ trỏ đến địa chỉ đẩu của ảnh
int x,y;
for(y = 0; y<bm.Height; y++)
{
for(x = 0; x<bm.Width; x++)
{
//Xử lý 3 byte của pixel
p[0] = 255;
p[1] = 255;
p[2] = 255;
//Chuyển con trỏ sang pixel kế tiếp
p += 3; // 2 pixel kế tiếp cách nhau 3 bytes
}//Xử lý xong 1 hàng
//Chuyển con trỏ xuông hàng kế tiếp
p += nOffset;
}
bm.UnLock(bmData);//giải phóng biến BitmapData


Đoạn lệnh trên sẽ biến bức ảnh thành màu trắng.

phanmemviet
27-09-2009, 15:58
Ảnh có rất nhiều đặc trưng (màu sắc, hình dạng, kết cấu). Bạn muốn trích chọn đặc trưng nào trong ảnh? Nếu mình đoán không nhầm thì bạn đang làm đề tài về nhận dạng hoặc là tìm kiếm ảnh phải không?

HungDo1988
30-09-2009, 02:07
Mình đang làm 1 đề tài về nhận dạng khuôn mặt.
Ý tưởng của để tài là: Đưa vào 1 ảnh và nhận dạng nó(tức là phát hiện ra ảnh đó đã có trong database chưa).
Ae nào đang nghiên cứu cái này và làm nó trên VC++2005 và openCV thì cùng trao đổi nhé. Tôi cung mới bắt đầu, mong ae chj giáo.(tài liệu, kinh nghiệm, kiến thức)
Thanks ae nhju nhju

thanhlyhai
19-11-2013, 15:02
mình muốn đọc chữ trên ảnh đấy ra một file txt thì làm ntn nhỉ?

rongvietnam123
19-11-2013, 20:36
mình muốn đọc chữ trên ảnh đấy ra một file txt thì làm ntn nhỉ?

Bạn dùng mắt để đọc rồi gõ vào một file txt là xong chứ có gì mà phải xoắn :D