Esempio n. 1
0
def lf_blur_subaperture(in_data, in_align, in_format, in_layout,
                        clen, xlen, ylen, ulen, vlen, u, v,
                        k, k_h_offset, k_width, k_v_offset,
                        dst_img_type, dst_byte_offset,
                        dst_col_stride, dst_row_stride,
                        output=None, threads=2):
    """
    Return a subaperture image (u,v) from given light field correlated
    with the given kernel
    """

    # calculate light field strides
    (lf_byte_offset,
     c_stride,
     x_stride, y_stride,
     u_stride, v_stride,
     full_size) = mlsl.strides(in_format, in_layout, in_align,
                               clen, xlen, ylen, ulen, vlen)

    if u < 0 or u >= ulen or v < 0 or v >= vlen:
        raise Error('u or v out of bounds')

    lf_byte_offset += u_stride * u + v_stride * v
    
    if threads < 1:
        raise Error('the argument threads must be positive')
    if threads < 2:
        return mlsl.correlate2(in_data, in_format, lf_byte_offset,
                              0, 0, x_stride, y_stride,
                              xlen, ylen,
                              dst_img_type, dst_byte_offset,
                              0, 0, dst_col_stride, dst_row_stride,
                              xlen, ylen,
                              xlen, ylen,
                              k, k_h_offset, k_width, k_v_offset, output=output)

    if threads > ylen:
        threads = ylen

    # create a shared output buffer if needed

    if output is None:
        max_col_reach = max(0, (dst_col_stride-1)*xlen)
        max_row_reach = max(0, (dst_row_stride-1)*ylen)
        max_reach = dst_byte_offset + max_col_reach + max_row_reach + struct.calcsize(dst_img_type)
        output = array.array(dst_img_type, '\x00'*max_reach)
        is_array = True
    else:
        is_array = False

    # create semaphores for task completion
    completed = threading.Semaphore(0)

    def thread_func(start,end):
        try:
            mlsl.correlate2(in_data, in_format, lf_byte_offset,
                           0, start, x_stride, y_stride,
                           xlen, ylen,
                           dst_img_type, dst_byte_offset,
                           0, start, dst_col_stride, dst_row_stride,
                           xlen, ylen,
                           xlen, end-start,
                           k, k_h_offset, k_width, k_v_offset, output=output)
        finally:
            completed.release()

    # start tasks

    for i in range(threads):
        start = int(round(1.0*i/threads*ylen))
        end = int(round(1.0*(i+1)/threads*ylen))
        thread.start_new_thread(thread_func, (start,end))

    # wait for task completion

    for i in range(threads):
        completed.acquire()

    if is_array:
        return output.tostring()
    else:
        return output
Esempio n. 2
0
def lf_blur3d(in_data, in_align, in_format, in_layout,
              out_align, out_format, out_layout,
              clen, xlen, ylen, ulen, vlen,
              var_x, var_y, var_z, pitch, slopes, out_data=None,
              threads=2):
    """
    Blur a light field such that the generated focal stack is blurred by
    the given variances (in microns^2).  The light field geometry
    is given by pitch and slopes (output from mlsl.geometry)

    """

    # calculate the light field strides
    (byte_offset,
     c_stride,
     x_stride, y_stride,
     u_stride, v_stride,
     full_size) = mlsl.strides(in_format, in_layout, in_align,
                               clen, xlen, ylen, ulen, vlen)

    (out_byte_offset,
     out_c_stride,
     out_x_stride, out_y_stride,
     out_u_stride, out_v_stride,
     out_full_size) = mlsl.strides(out_format, out_layout,
                                   out_align,
                                   clen, xlen, ylen, ulen, vlen)

    out_pixel_size = struct.calcsize(out_format)

    if out_full_size % out_pixel_size:
        out_full_size += out_pixel_size - (out_full_size % out_pixel_size)

    # allocate an output buffer if it's not there
    make_string = False
    if out_data is None:
        make_string = True
        out_data = array.array(out_format, '\x00'*out_full_size)

    all_jobs = []

    # do some precalculations
    var_x_norm = var_x / (2*math.pi)
    var_y_norm = var_y / (2*math.pi)
    var_z_norm = var_z / (2*math.pi)

    for (u,v) in slopes:
        # get the actual slope for a u,v
        u_f, v_f, u_s2, v_s2 = slopes[(u,v)]

        print u_f, v_f

        # calculate new covariance matrix
        var_h_norm = var_x_norm + var_z_norm * u_f * u_f
        var_v_norm = var_y_norm + var_z_norm * v_f * v_f
        var_c_norm = u_f * v_f * var_z_norm

        # rescale variances
        var_h = 2*math.pi * var_h_norm / (pitch*pitch)
        var_v = 2*math.pi * var_v_norm / (pitch*pitch)
        var_c = 2*math.pi * var_c_norm / (pitch*pitch)

        print var_h, var_v, var_c

        # create Gaussian kernel
        kernel = mlsl.gaussian2(var_h, var_v, var_c)

        # iterate over color channels
        for c in range(clen):
            src_byte_offset = byte_offset + c*c_stride + u*u_stride + v*v_stride
            dst_byte_offset = out_byte_offset + c*out_c_stride + u*out_u_stride + v*out_v_stride
            # append to job list
            all_jobs.append((src_byte_offset, dst_byte_offset, kernel))

    if len(all_jobs) < threads:
        threads = len(all_jobs)

    # threads

    done = threading.Semaphore(0)

    def work_thread(jobs):
        try:
            for (src_byte_offset, dst_byte_offset, kernel) in jobs:
                k, k_h_offset, k_width, k_v_offset = kernel
                mlsl.correlate2(in_data, in_format, src_byte_offset,
                               0, 0, x_stride, y_stride,
                               xlen, ylen,
                               out_format, dst_byte_offset,
                               0, 0, out_x_stride, out_y_stride,
                               xlen, ylen,
                               xlen, ylen,
                               k, k_h_offset, k_width, k_v_offset, output=out_data)
        finally:
            done.release()

    for i in range(threads):
        job_start = int(round(1.0*len(all_jobs)*i/threads))
        job_end = int(round(1.0*len(all_jobs)*(i+1)/threads))
        job_segment = all_jobs[job_start:job_end]
        thread.start_new_thread(work_thread,(job_segment,))

    for i in range(threads):
        done.acquire()

    if make_string:
        out_data = out_data.tostring()

    return out_data