[Thực chiến] Tìm hình có diện tích lớn nhất

Đây là một bài tập tổng hợp để các code thủ luyện cơ xem mình cơ mình đã 6 múi chưa :smile:
Nhất là ai muốn theo nghiệp xử lý ảnh :slight_smile:

Trong một bức ảnh có nhiều hình với hình dạng khác nhau. Hãy dùng mọi “thủ đoạn” mà bạn biết để tìm hình có diện tích lớn nhất. Xuất ra diện tích của hình đó (S=? pixel) và tọa độ hình đó (Xmin ? Ymin? Xmax? Y max?).

Gốc tọa độ là góc trên bên trái.
Ảnh là bitmap 24 bit.
Bắt đầu nào anh em :slight_smile:

3 Likes

Đây là ảnh bmp đổi đuôi thành jpg thì phải
À, có API ăn sẵn nè các thím :smile: http://mkweb.bcgsc.ca/color-summarizer/?api

2 Likes

Đúng rồi, qua kiểm tra bằng lệnh file thì nó là map.bmp.jpg: PC bitmap, Windows 3.x format, 800 x 600 x 24.
API đó chỉ làm việc với jpeg và png mà?

Không tính hình trắng thì hình như cái màu đỏ là hình có diện tích lớn thứ 2 RGB(237, 28, 36) = 52080. Còn code thì đáp án đúng mới dám up :relieved: mình mặt mỏng nên sợ quê lắm.
Thủ đoạn mình có dùng: dùng mắt để tra google cái màu với tự so sánh rồi chọn ra số thứ 2 cho nhanh (khỏi phải code) :joy:

Thực ra thì theo cái trang web kia thì màu xanh của hình tròn là lớn nhất, 11.14%. Màu đỏ chỉ 10.73%.
Còn vụ ảnh thì mình tải ảnh về, mở paint rồi lưu thành png là xong mà. Hoặc thậm chí copy ảnh rồi paste luôn ở đây.

2 Likes

sử dụng opencv thì dùng contour tìm các đường viên bao quanh đối tượng, rồi sắp xếp contour giảm dần rồi chọn cái thứ 2, khi đã tìm được contour chưa hình cần tìm thì đếm số pixel trong vùng contour đó, màu thì các pixel trong 1 hình đều có cùng 1 màu thì phải , nên lấy 1 pixel trong vùng contour cần tìm, rồi lấy r,g,b :v còn làm tay thì cũng căng đấy nhỉ

:~ Chắc là duyệt từng pixel, lấy mã màu, bỏ vô hash table rồi đếm dần. Có thể làm vài biện pháp để đơn giản màu sắc lại đề phòng hình nhiều màu quá :grin:

Mà nói vậy thôi chứ không biết code :joy:

4 Likes

hix, cái này đếm pixel, đơn giản mà, số pixel lớn nhì là xem như diện tích lớn nhì, xài cái canvas html ấy để đồng đạo xem thử luôn…:horse_racing:

Tư tưởng lớn gặp nhau :smile:

2 Likes

Nghe chừng dễ quá đổi lại cái đề cho nó “đánh võng” tý nữa.
Lại nào anh em :smile:

1 Like

Ảnh ở đây là ảnh bitmap để không bị nén làm sai màu sẽ ảnh hưởng đến kết quả.
Nhưng DNH không cho up bitmap nên táng thêm jpg đằng sau để lừa nó :smile:
Anh em tải về bỏ đuôi jpg đi là chiến.

1 Like

DFS những ô cùng màu thôi:

def dfs(x,y):

    st = [(x,y)]
    ans = 0
    while len(st):
        _x,_y = st.pop()
        if not visited[_y][_x]:
            ans+=1
            visited[_y][_x] = True
        for dy in range(-1,2):
            for dx in range(-1,2):
                xx = _x+dx
                yy = _y+ dy
                if xx<0 or xx>=width or yy<0 or yy>=height or visited[yy][xx] or not same(color[yy][xx],color[y][x]):
                    continue
                st.append((xx,yy))
    return ans
for i in range(height):
    for j in range(width):
        if not visited[i][j] :
            #print(i,j)
            ans = dfs(j,i)
            if ans>10**4:
                print(ans,color[i][j])

##update
Sau khi download lại ảnh (đúng size) thì kết quả:
###Có màu

214047 (255, 255, 255)
52080 (237, 28, 36)
44999 (255, 242, 0)
47252 (163, 73, 164)
53228 (0, 162, 232)
33378 (34, 177, 76)
35016 (255, 174, 201)

###Màu đỏ

214047 (255, 255, 255)
52080 (237, 28, 36)
44999 (237, 28, 36)
47252 (237, 28, 36)
53228 (237, 28, 36)
33378 (237, 28, 36)
35016 (237, 28, 36)
1 Like

Ảnh kích thước 800x600 = 480.000 pixel thôi mà.
Kết quả kia độc màu trắng đã hơn 500.000 pixel :wink:

1 Like

Giờ dễ nhất là tăng constrast lên, dùng magic wand để tách thành các layer, tô cho tất cả các layer đều chỉ một màu (ví dụ 255,0,0) rồi đặt lại vị trí cũ. Có 6 shapes, vậy ta sẽ lưu thành 6 file khác nhau có cùng kích thước với hình ban đầu, mỗi file chỉ có 1 shape ở đúng vị trí của nó.

1 Like

số 4 bự nhứt nhoa :kissing_heart:

1 Like

Đã quy về 1 màu rồi đó bạn. Vì 6 màu nó dễ quá chắc anh em không hứng :slight_smile:

1 Like

Chưa có đáp số nè :slight_smile:

1 Like

fix lại rồi, quên check 1 điểm bị đếm lại nhiều lần

1 Like

đáp số rồi đó, mảnh 4 diện tích là 52823.5 trắc trắn rầu :triumph:

1 Like

Sao kết quả lại có .5 :flushed:

1 Like

hehe tui cũng loang nhưng mà loang lấy border của mỗi hình, như trong cái hình trên là đường viền màu xanh lá đó. Sau đó xài Boost.Geometry boost::geometry::area() để lấy diện tích hình đó, nên nó mới ra .5

tại có viết cái clone Gunbound, để làm map thì mỗi piece coi như là 1 cục, mấy cái vehicle cho chạy trên cái cục đó nên chỉ cần đường viền là đủ, ko cần từng pixel một, tui viết cái tool load map chỉ cần 1 điểm trong cục đó là truy ra được đường viền của cục đó. Với hình này cho 6 điểm lấy 6 cục, rồi tính diện tích dễ dàng :stuck_out_tongue:

hàm truy đường viền nó lấy từng pixel một trên đường viền, cho vô boost::geometry::simplify() cho nó bỏ bớt mấy điểm ko cần đi, tuy ko chính xác 100% nhưng cũng chính xác 99%, ví dụ mảng 2 là hcn chỉ cần 4 điểm nó lại cho ra 6 điểm, gần đúng thôi. Kết quả ra 1 cái 52k 1 cái 51k chắc chênh lệch ko nhiều đâu

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?