2011-12-07 92 views
5

Tôi đang cố gắng đếm tất cả các điểm ảnh màu trắng trong hình ảnh nhị phân OpenCV. Mã hiện tại của tôi như sau:Đếm các điểm ảnh 'trắng' trong hình ảnh nhị phân opencv (hiệu quả)

whitePixels = 0; 
    for (int i = 0; i < height; ++i) 
    for (int j = 0; j < width; ++j) 
     if (binary.at<int>(i, j) != 0) 
     ++whitePixels; 

Tuy nhiên, sau khi lập hồ sơ với gprof tôi nhận thấy đây là một đoạn mã rất chậm và nút cổ chai lớn trong chương trình.

Có phương pháp nào có thể tính toán cùng một giá trị nhanh hơn không?

+0

Bạn đã thử thay đổi chiều cao và chiều rộng? Tôi có nghĩa là looping trên chiều rộng và sau đó chiều cao? Điều này có thể cải thiện vòng lặp, phụ thuộc vào cách hình ảnh được bố trí trong bộ nhớ. –

+2

Bạn có thể truy cập dữ liệu hình ảnh trực tiếp thay vì thông qua hàm at() này không? – jrok

+0

Làm như jrok gợi ý có lẽ sẽ nhanh hơn. Tôi tự hỏi, nếu [faq này] (http://opencv.willowgarage.com/wiki/faq#How_to_access_image_pixels) có liên quan. – Brian

Trả lời

20

cvCountNonZero. Thông thường, việc triển khai OpenCV của một tác vụ được tối ưu hóa rất nhiều.

+3

@karlphillip bạn có nghĩa là ['cv :: countNonZero'] (http://opencv.willowgarage.com/documentation/cpp/core_operations_on_arrays.html#cv-countnonzero)? –

+0

Hoàn hảo, được tối ưu hóa, được xây dựng trong chức năng. Chỉ cần những gì tôi đang tìm kiếm. –

+0

Đã thêm liên kết tài liệu hiện tại vào câu trả lời (có thể được cập nhật trong tương lai, không giống như nhận xét này). – handle

0

Bạn có thể sử dụng tính toán song song. Bạn chia hình ảnh trong N phần và chạy mã của bạn trong chủ đề differents sau đó bạn sẽ có được kết quả của mỗi chủ đề và sau này bạn có thể thêm kết quả này để có được số tiền cuối cùng.

+1

Thuật toán của Bill có thể, nếu được triển khai đúng cách, bị ràng buộc về bộ nhớ thay vì bị ràng buộc CPU. Trên một máy tính để bàn bình thường, thường song song không phải là hữu ích cho các nhiệm vụ ràng buộc bộ nhớ. – Brian

-2

Pixel cuối cùng trong một hàng thường tiếp theo là điểm ảnh đầu tiên trong hàng tiếp theo (mã C):

limit=width*height; 
i=0; 
while (i<limit) 
{ 
    if (binary.at<int>(0,i) != 0) ++whitePixels; 
    ++i; 
} 
+0

Hoặc thực hiện nó như một con trỏ trượt sẽ loại bỏ chỉ mục. –

+0

Và/hoặc kiểm tra hai lần tại [i] và tại [i + 1] và thêm 2 vào chỉ mục/con trỏ. Điều này sẽ giảm một nửa các vòng yêu cầu. –

+0

Một thử nghiệm liên tục nên được thực hiện trên ma trận trước với isContinuous(). Nếu ma trận không liên tục, phương pháp này sẽ thất bại. –

-2

Trên thực tế binary.at<int>(i, j) là truy cập chậm!

Đây là mã đơn giản truy cập nhanh hơn mã của bạn.

for (int i = 0; i < height; ++i) 
{ 
uchar * pixel = image.ptr<uchar>(i); 
    for (int j = 0; j < width; ++j) 
{ 
    if(pixel[j]!=0) 
    { 
     //do your job 
    } 
} 
} 
Các vấn đề liên quan