2013-03-21 45 views
5

Tôi bắt đầu viết mã chương trình xử lý hình ảnh từ các thuật toán xử lý hình ảnh khác nhau, chủ yếu từ công việc René Schulte, và khi điểm chuẩn, tôi nhận thấy rằng từ tất cả các hiệu ứng tôi có thể tìm thấy từ các nguồn khác nhau, mã để áp dụng hiệu ứng 'Softlight' là chậm nhất. Tôi không giỏi trong việc tối ưu hóa phương trình, nhưng tôi cảm thấy rằng bộ lọc dựa trên công thức có thể lặp lại các biến không có lý do.Công thức này lặp đi lặp lại hoặc tối ưu

Điều này có thể tóm tắt trong điều gì đó ngắn hơn hoặc nhanh hơn không?

// Basically, b is from Image A, and t from Image B 
int csoftLight(float b, float t) 
     { 
      b /= 255; 
      t /= 255; 

      return (int)((t < 0.5) ? 255 * ((1 - 2 * t) * b * b + 2 * t * b) : 255 * ((1 - (2 * t - 1)) * b + (2 * t - 1) * (Math.Pow(b, 0.5)))); 
     } 

[Edit - Kết quả tìm kiếm bằng cách sử dụng phương trình Mohammed Hossain tìm thấy khoảng softlight trong PS]

// Input: 137 and 113 

// Byte version: 
int other = ((byte)((B < 128) ? (2 * ((A >> 1) + 64)) * ((float)B/255) : (255 - (2 * (255 - ((A >> 1) + 64)) * (float)(255 - B)/255)))); 
// Returns 116  


// float version: 
int res = (int)((t < 0.5) ? 255 * ((1 - 2 * t) * b * b + 2 * t * b) : 255 * ((1 - (2 * t - 1)) * b + (2 * t - 1) * (Math.Pow(b, 0.5)))); 
// Returns 129 

[Chỉnh sửa]

Dưới đây là các thuật toán nhanh nhất dựa trên Mohammed Hossain câu trả lời:

int csoftLight(byte A, byte B) 
{ 
    return (int)((A < 128) ? (2 * ((B >> 1) + 64)) * ((float)A/255) : (255 - (2 * (255 - ((B >> 1) + 64)) * (float)(255 - A)/255)));   
} 
+0

tôi hy vọng rằng các trình biên dịch sẽ làm loại bỏ subexpression thông thường, nhưng khi floating- điểm được tham gia ... – nneonneo

+0

Và googling tên của guy mà thêm mã này vào nguồn gốc trả về không có gì.Tôi sẽ kết thúc gọi là coder! –

+0

Số học hoạt động trên phao là tốn kém hơn sau đó trên số nguyên.Nếu nó có thể thay đổi kiểu tham số thành int, sau đó tôi có thể cung cấp giải pháp –

Trả lời

4

Câu trả lời này sẽ giúp bạn và làm rõ một số điều sau: How does photoshop blend two images together?

Một trong các phương trình là thuật toán ánh sáng yếu.

#define ChannelBlend_SoftLight(A,B) ((uint8)((B < 128)?(2*((A>>1)+64))*((float)B/255):(255-(2*(255-((A>>1)+64))*(float)(255-B)/255)))) //not very accurate 

Điều quan trọng là tránh vận hành gốc bình phương tốn kém và ít quan trọng hơn sử dụng toán tử thay đổi bit ở vị trí chia cho 2 (cần tối ưu hóa bằng trình biên dịch thông minh). Nó cũng sử dụng nhiều hoạt động số nguyên hơn so với các hoạt động nổi, nhanh hơn.

Dưới đây là một công thức (ưu đãi cho các chủ sở hữu của this mà chuyển sang hoạt động của biến, và nó dường như hoạt động ...

#define ChannelBlend_SoftLight(A,B) (uint8)(((A < 128) ? (2 * ((B >> 1) + 64)) * ((float) A/255) : (255 - (2 * (255 - ((B >> 1) + 64)) * (float) (255 - A)/255)))); 
+0

Ồ, bạn có chính xác ngữ cảnh của phương trình. Megaupvote! –

+0

Không biết tôi đang làm gì sai, nhưng nó không trả về đúng hình ảnh: 'int csoftLight (byte A, byte B) { return ((byte) ((B <128)? (2 * ((A >> 1) + 64)) * ((phao) B/255): (255 - (2 * (255 - ((A >> 1) + 64)) * (phao) (255 - B)/255)))); } ' –

+1

Bạn phải gọi cho mỗi kênh của pixel; nếu bạn đang làm điều này trong RGB, sau đó bạn phải gọi nó ba lần (R, G, B). Sản phẩm cuối cùng là ba giá trị (R, G, B) là ba kênh của điểm ảnh đầu ra. Bạn hiện đang làm điều này? –

Các vấn đề liên quan