def mix2d(a): """ Calculate a DST-DCT-hybrid transform (DST in first direction, DCT in second one), jury-rigged from padded rFFT (anti-symmetrically in first direction, symmetrically in second direction). """ # NOTE: LCODE 3D uses x as the first direction, thus the confision below. M, N = a.shape # /(0 1 2 0)-2 -1 \ +----> x # / 1 2 \ | (0 3 4 0)-4 -3 | | (M) # | 3 4 | mixed-symmetrically | (0 5 6 0)-6 -5 | | # | 5 6 | padded to | (0 7 8 0)-8 -7 | v # \ 7 8 / | 0 +5 +6 0 -6 -5 | # \ 0 +3 +4 0 -4 -3 / y (N) p = cp.zeros((2 * M + 2, 2 * N - 2)) # wider than before p[1:M + 1, :N] = a p[M + 2:2 * M + 2, :N] = -cp.flipud(a) # flip to right on drawing above p[1:M + 1, N - 1:2 * N - 2] = cp.fliplr(a)[:, :-1] # flip down on drawing above p[M + 2:2 * M + 2, N - 1:2 * N - 2] = -cp.flipud(cp.fliplr(a))[:, :-1] # Note: the returned array is wider than the input array, it is padded # with zeroes (depicted above as a square region marked with round braces). return -cp.fft.rfft2(p)[:M + 2, :N].imag # FFT, cut a corner with 0s, -imag
def test_orientation(): orient = regionprops(SAMPLE)[0].orientation # determined with MATLAB assert_almost_equal(orient, -1.4663278802756865) # test diagonal regions diag = cp.eye(10, dtype=int) orient_diag = regionprops(diag)[0].orientation assert_almost_equal(orient_diag, -math.pi / 4) orient_diag = regionprops(cp.flipud(diag))[0].orientation assert_almost_equal(orient_diag, math.pi / 4) orient_diag = regionprops(cp.fliplr(diag))[0].orientation assert_almost_equal(orient_diag, math.pi / 4) orient_diag = regionprops(cp.fliplr(cp.flipud(diag)))[0].orientation assert_almost_equal(orient_diag, -math.pi / 4)
def take_filter(N, filter): os = 4 d = 0.5 Ne = os * N t = cp.arange(0, Ne / 2 + 1) / Ne if (filter == 'ramp'): wfa = Ne * 0.5 * wint(12, t) # .*(t/(2*d)<=1)%compute the weigths elif (filter == 'shepp-logan'): wfa = Ne * 0.5 * wint(12, t) * cp.sinc(t / (2 * d)) * (t / d <= 2) elif (filter == 'cosine'): wfa = Ne * 0.5 * wint(12, t) * cp.cos(cp.pi * t / (2 * d)) * (t / d <= 1) elif (filter == 'cosine2'): wfa = Ne * 0.5 * wint(12, t) * (cp.cos(cp.pi * t / (2 * d)))**2 * (t / d <= 1) elif (filter == 'hamming'): wfa = Ne * 0.5 * wint( 12, t) * (.54 + .46 * cp.cos(cp.pi * t / d)) * (t / d <= 1) elif (filter == 'hann'): wfa = Ne * 0.5 * wint( 12, t) * (1 + np.cos(cp.pi * t / d)) / 2.0 * (t / d <= 1) elif (filter == 'parzen'): wfa = Ne * 0.5 * wint(12, t) * pow(1 - t / d, 3) * (t / d <= 1) wfa = wfa * (wfa >= 0) wfamid = cp.array([2 * wfa[0]]) tmp = wfa wfa = cp.concatenate((cp.flipud(tmp[1:]), wfamid)) wfa = cp.concatenate((wfa, tmp[1:])) wfa = wfa[:-1].astype('float32') return wfa
def dst2d(a): """ Calculate DST-Type1-2D, jury-rigged from anti-symmetrically-padded rFFT. """ assert a.shape[0] == a.shape[1] N = a.shape[0] # / 0 0 0 0 0 0 \ # 0 0 0 0 | 0 /1 2\ 0 -2 -1 | # 0 /1 2\ 0 anti-symmetrically | 0 \3 4/ 0 -4 -3 | # 0 \3 4/ 0 padded to | 0 0 0 0 0 0 | # 0 0 0 0 | 0 -3 -4 0 +4 +3 | # \ 0 -1 -2 0 +2 +1 / p = cp.zeros((2 * N + 2, 2 * N + 2)) p[1:N+1, 1:N+1], p[1:N+1, N+2:] = a, -cp.fliplr(a) p[N+2:, 1:N+1], p[N+2:, N+2:] = -cp.flipud(a), +cp.fliplr(cp.flipud(a)) # after padding: rFFT-2D, cut out the top-left segment, take -real part return -cp.fft.rfft2(p)[1:N+1, 1:N+1].real
def dct2d(a): """ Calculate DCT-Type1-2D, jury-rigged from symmetrically-padded rFFT. """ assert a.shape[0] == a.shape[1] N = a.shape[0] # //1 2 3 4\ 3 2 \ # /1 2 3 4\ | |5 6 7 8| 7 6 | # |5 6 7 8| symmetrically | |9 A B C| B A | # |9 A B C| padded to | \D E F G/ F E | # \D E F G/ | 9 A B C B A | # \ 5 6 7 8 7 6 / p = cp.zeros((2 * N - 2, 2 * N - 2)) p[:N, :N] = a p[N:, :N] = cp.flipud(a)[1:-1, :] # flip to right on drawing above p[:N, N:] = cp.fliplr(a)[:, 1:-1] # flip down on drawing above p[N:, N:] = cp.flipud(cp.fliplr(a))[1:-1, 1:-1] # bottom-right corner # after padding: rFFT-2D, cut out the top-left segment, take -real part return -cp.fft.rfft2(p)[:N, :N].real
def convolve2dcp(image, kernel): # This function which takes an image and a kernel # and returns the convolution of them # Args: # image: a numpy array of size [image_height, image_width]. # kernel: a numpy array of size [kernel_height, kernel_width]. # Returns: # a numpy array of size [image_height, image_width] (convolution output). kernel = cp.flipud(cp.fliplr(kernel)) # Flip the kernel output = cp.zeros_like(image) # convolution output # Add zero padding to the input image image_padded = cp.zeros((image.shape[0] + 2, image.shape[1] + 2)) image_padded[1:-1, 1:-1] = image for x in range(image.shape[1]): # Loop over every pixel of the image for y in range(image.shape[0]): # element-wise multiplication of the kernel and the image output[y, x] = (kernel * image_padded[y:y + 3, x:x + 3]).sum() return output
else: while True: # Waiting for data from master process chunk_shape = comm.recv(source=MASTER_PROCESS, tag=SETUP_TAG) if chunk_shape == -1: break else: amps = comm.recv(source=MASTER_PROCESS, tag=AMPS_TAG) chunk = comm.recv(source=MASTER_PROCESS, tag=DATA_TAG, status=status) tag = status.Get_tag() cusig = cupy.asarray(chunk, dtype=cupy.float32) cusig = cusig - cupy.mean(cusig) cusig = cusignal.sosfilt(sos, cusig) cusig = cupy.flipud(cusig) cusig = cusignal.sosfilt(sos, cusig) cusig = cupy.flipud(cusig) proc_channel_scales = cupy.asarray(chunk[:, -1], dtype=cupy.float32)[:, None] # cusig=cusig*proc_channel_scales result_array = cupy.asnumpy( cusig[:, -(chunk.shape[1] - sample_chunk_size):]) comm.send(result_array, dest=MASTER_PROCESS, tag=RESULT_TAG) if iproc == MASTER_PROCESS: in_fid.close() out_fid.close() if ram_copy: out_ramfile.save() del in_ramfile, out_ramfile
def convolve_gpu_chunked(x, b, pad='flip', nwin=DEFAULT_CONV_CHUNK, ntap=500, overlap=2000): """Chunked GPU FFT-based convolution for large arrays. This memory-controlled version splits the signal into chunks of n samples. Each chunk is tapered in and out, the overlap is designed to get clear of the taper splicing of overlaping chunks is done in a cosine way. param: pad None, 'zeros', 'constant', 'flip' """ x = cp.asarray(x) b = cp.asarray(b) assert b.ndim == 1 n = x.shape[0] assert overlap >= 2 * ntap # create variables, the gain is to control the splicing y = cp.zeros_like(x) gain = cp.zeros(n) # compute tapers/constants outside of the loop taper_in = (-cp.cos(cp.linspace(0, 1, ntap) * cp.pi) / 2 + 0.5)[:, cp.newaxis] taper_out = cp.flipud(taper_in) assert b.shape[0] < nwin < n # this is the convolution wavelet that we shift to be 0 lag bp = cp.pad(b, (0, nwin - b.shape[0]), mode='constant') bp = cp.roll(bp, -b.size // 2 + 1) bp = cp.fft.rfft(bp, n=nwin)[:, cp.newaxis] # this is used to splice windows together: cosine taper. The reversed taper is complementary scale = cp.minimum( cp.maximum(0, cp.linspace(-0.5, 1.5, overlap - 2 * ntap)), 1) splice = (-cp.cos(scale * cp.pi) / 2 + 0.5)[:, cp.newaxis] # loop over the signal by chunks and apply convolution in frequency domain first = 0 while True: first = min(n - nwin, first) last = min(first + nwin, n) # the convolution x_ = cp.copy(x[first:last, :]) x_[:ntap] *= taper_in x_[-ntap:] *= taper_out x_ = cp.fft.irfft(cp.fft.rfft(x_, axis=0, n=nwin) * bp, axis=0, n=nwin) # this is to check the gain of summing the windows tt = cp.ones(nwin) tt[:ntap] *= taper_in[:, 0] tt[-ntap:] *= taper_out[:, 0] # the full overlap is outside of the tapers: we apply a cosine splicing to this part only if first > 0: full_overlap_first = first + ntap full_overlap_last = first + overlap - ntap gain[full_overlap_first:full_overlap_last] *= (1. - splice[:, 0]) gain[full_overlap_first:full_overlap_last] += tt[ntap:overlap - ntap] * splice[:, 0] gain[full_overlap_last:last] = tt[overlap - ntap:] y[full_overlap_first:full_overlap_last] *= (1. - splice) y[full_overlap_first:full_overlap_last] += x_[ntap:overlap - ntap] * splice y[full_overlap_last:last] = x_[overlap - ntap:] else: y[first:last, :] = x_ gain[first:last] = tt if last == n: break first += nwin - overlap return y
def correct(img, shift=True): """Correct the orientation of the obtained image.""" if shift: return cp.fliplr(cp.flipud(cp.fft.fftshift(img))) else: return cp.fliplr(cp.flipud(img))
row = cp_density_stack.shape[1] col = cp_density_stack.shape[2] print("sta_dens = " + str(sta_dens)) print("row = " + str(row)) print("col = " + str(col)) print("") average_dens = cp.average(cp_density_stack, axis=(1, 2)) #print(average_dens) #print(average_dens.shape) temp_dens = cp.zeros(cp_density_stack.shape) if (temp_dens_flag == 1): temp_dens_2D = Image.open(temp_dens_name) temp_dens_2D = cp.asarray(temp_dens_2D, dtype="float32") temp_dens_2D = cp.flipud(temp_dens_2D) temp_dens_2D_ave = cp.average(temp_dens_2D) temp_dens_2D[:, :] = temp_dens_2D[:, :] - temp_dens_2D_ave temp_dens[:, :, :] = temp_dens_2D[:, :] else: temp_dens[:, :, :] = cp_density_stack[0, :, :] #average_temp_dens=cp.average(temp_dens,axis=(1,2)) average_dens_expa = cp.zeros(cp_density_stack.shape) for i in range(sta_dens): average_dens_expa[i, :, :] = average_dens[i] average_temp_dens_expa = cp.zeros(cp_density_stack.shape) average_temp_dens_expa[:, :, :] = average_dens[0]
mrc.close R_dens_sort=R_dens[np.argsort(NOR),:,:] R_dens_sort = cp.asnumpy(R_dens_sort)#cupy配列 ⇒ numpy配列に変換 with mrcfile.new(header + '_final_rdens_sort.mrc', overwrite=True) as mrc: mrc.set_data(R_dens_sort.real) mrc.close cp_sup_sort=cp_sup[np.argsort(NOR),:,:] cp_sup_sort = cp.asnumpy(cp_sup_sort)#cupy配列 ⇒ numpy配列に変換 with mrcfile.new(header + '_final_sup_sort.mrc', overwrite=True) as mrc: mrc.set_data(cp_sup_sort.real) mrc.close R_dens_min_NOR=R_dens[n_min_NOR,:,:] R_dens_min_NOR=cp.flipud(R_dens_min_NOR) R_dens_min_NOR = cp.asnumpy(R_dens_min_NOR)#cupy配列 ⇒ numpy配列に変換 foname=header + "_final_rdens_min_NOR.tif" tifffile.imsave(foname ,R_dens_min_NOR.real) foname=header + "_final_adens_min_NOR.tif" tifffile.imsave(foname ,np.absolute(R_dens_min_NOR)) cp_sup_min_NOR=cp_sup[n_min_NOR,:,:] cp_sup_min_NOR=cp.flipud(cp_sup_min_NOR) cp_sup_min_NOR = cp.asnumpy(cp_sup_min_NOR)#cupy配列 ⇒ numpy配列に変換 foname=header + "_final_sup_min_NOR.tif" tifffile.imsave(foname ,cp_sup_min_NOR) cp_sup = cp.asnumpy(cp_sup)