2012-12-15 42 views
6

đây là bài tập của chúng tôi trong bài tập về nhà xử lý hình ảnh. mã của tôi đang hoạt động tốt. tôi muốn được trợ giúp về tối ưu hóa mã.Chuyển đổi 2D trong MATLAB - tối ưu hóa mã

function C = convolve_slow(A,B) 
(file name is accordingly convolve_slow.m) 
This routine performs convolution between an image A and a mask B. 
Input:  A - a grayscale image (values in [0,255]) 
      B - a grayscale image (values in [0,255]) serves as a mask in the convolution. 
Output:  C - a grayscale image (values in [0,255]) - the output of the convolution. 
         C is the same size as A. 

Method: Convolve A with mask B using zero padding. Assume the origin of B is at 
    floor(size(B)/2)+1. 
Do NOT use matlab convolution routines (conv,conv2,filter2 etc). 
Make the routine as efficient as possible: Restrict usage of for loops which are expensive (use matrix multiplications and matlab routines such as dot etc). 
To simplify and reduce ifs, you should pad the image with zeros before starting your convolution loop. 
Do not assume the size of A nor B (B might actually be larger than A sometimes). 

Đây là giải pháp của chúng tôi

function [ C ] = convolve_slow(A,B) 
%This routine performs convolution between an image A and a mask B. 
% Input:  A - a grayscale image (values in [0,255]) 
%    B - a grayscale image (values in [0,255]) serves as a mask in the convolution. 
% Output:  C - a grayscale image (values in [0,255]) - the output of the convolution. 
%    C is the same size as A. 
% 
% Method: Convolve A with mask B using zero padding. Assume the origin of B is at floor(size(B)/2)+1. 
% init C to size A with zeros 
C = zeros(size(A)); 
% make b xy-reflection and vector 
vectB = reshape(flipdim(flipdim(B,1),2)' ,[] , 1); 
% padding A with zeros 
paddedA = padarray(A, [floor(size(B,1)/2) floor(size(B,2)/2)]); 
% Loop over A matrix: 
for i = 1:size(A,1) 
    for j = 1:size(A,2) 
     startAi = i; 
     finishAi = i + size(B,1) - 1; 
     startAj = j; 
     finishAj = j + size(B,2) - 1; 
     vectPaddedA = reshape(paddedA(startAi :finishAi,startAj:finishAj)',1,[]); 
     C(i,j) = vectPaddedA* vectB; 
    end 
end 
end 

kể từ khi tôi mới để xử lý hình ảnh và Matlab. bạn có thể vui lòng giúp tôi với tối ưu hóa mã, cụ thể với các hoạt động dựa trên ma trận. là nó có thể không sử dụng vòng?

+1

được bạn cho phép sử dụng fft2 và ifft2 chức năng theo bất kỳ cách nào? Nếu đó là một cách để có được một giải pháp khá nhanh. – MarkV

+0

Không, xin lỗi không có fft, khái niệm chính là chúng tôi thực hiện một convolution để tìm hiểu cách thức hoạt động. nó hoạt động tốt! bây giờ tôi muốn xem nếu có một cách để làm điều đó tốt hơn. – Gilad

Trả lời

5

Nếu không viết mã một cách rõ ràng, tôi có thể thấy cách để đặt xuống một vòng chính for. Về cơ bản, hãy nghĩ về ma trận A và B là các vectơ cột bằng cách mở mỗi cột của A và B thành một vec-tơ (đó là cách nó được lưu trữ bên trong trong MATLAB). Sau đó, mỗi tọa độ (i,j) của A có thể được ánh xạ tới chỉ mục tuyến tính k (sử dụng hàm sub2ind ví dụ). Sau đó, đối với mỗi chỉ số tuyến tính trong nội dung của A (bỏ qua padding), tính toán danh sách các chỉ số tuyến tính tương ứng với một submatrix xung quanh chỉ số tuyến tính này (đó có thể là phần khó nhất ở đây). Sau đó, tính toán sản phẩm chấm của A(theseIndices)B(:). Với phương pháp này bạn chỉ cần lặp qua từng chỉ số tuyến tính của A.

3

Dont biết nếu điều này là nhanh hơn, nhưng ít nhất không có cho vòng (mà không có nghĩa là nó phải được nhanh hơn nữa trong các phiên bản matlab gần đây)

function A = tmpConv(A,B) 

    filterSize = size(B,1); 
    filterSize2 = floor(filterSize/2); 
    inputSize = size(A); 

    A = padarray(A,[filterSize2 filterSize2]); 

    f = repmat(B(:),[1 inputSize(1)*inputSize(2)]); 
    A = im2col(A,[filterSize filterSize]); 
    A = reshape(sum(A.*f),inputSize); 
+0

Điều này tính toán mối tương quan, không chập chững. Bạn sẽ phải xoay bộ lọc 180 độ cho điều đó. Ngoài ra, việc xây dựng ma trận 'f' là không cần thiết, vì kết quả tương tự được thực hiện bằng phép nhân ma trận' A'' với vectơ lọc (đảo ngược). – Joost