void CaffeMobile::putImage(AndroidBitmapInfo* info, void* pixels, const vector<Blob<float>*>& resImage) { Blob<float> * srcBlob = *resImage.data(); LOG(DEBUG) << "srcBlob received"; vector<int> shape = {1, 3, (int) info->width, (int) info->height }; LOG(DEBUG) << "shape configured"; Blob<float>* imgBlob = new Blob<float>(); LOG(DEBUG) << "Blob created"; imgBlob->Reshape(shape); LOG(DEBUG) << "imgBlob reshaped"; imgBlob->CopyFrom(*srcBlob, false, true); LOG(DEBUG) << "imgBlob copied"; int size = imgBlob->count(); LOG(DEBUG) << "imgBlob size is: " << size; /*Partially from https://github.com/ruckus/android-image-filter-ndk*/ uint32_t* pixelRow; int ix, iy, red, green, blue; for(iy = 0; iy < (int) info->height; iy++){ pixelRow = (uint32_t*) pixels; for(ix =0; ix < (int) info->width; ix++){ red = (int) clip(imgBlob->data_at(0,0,iy,ix), 0, 255); green = (int) clip(imgBlob->data_at(0,1,iy,ix), 0, 255); blue = (int) clip(imgBlob->data_at(0,2,iy,ix), 0, 255); pixelRow[ix] = ((red << 16) & 0x00FF0000) | ((green << 8) & 0x0000FF00) | (blue & 0x000000FF); } pixels = (char*)pixels + info->stride; } LOG(DEBUG) << "before return putImage " << size; return; }
TYPED_TEST(DeconvolutionLayerTest, TestNDAgainst2D) { typedef typename TypeParam::Dtype Dtype; const int kernel_h = 11; const int kernel_w = 13; vector<int> bottom_shape(4); bottom_shape[0] = 15; bottom_shape[1] = 12; bottom_shape[2] = kernel_h * 2; bottom_shape[3] = kernel_w * 2; FillerParameter filler_param; GaussianFiller<Dtype> filler(filler_param); for (int i = 0; i < this->blob_bottom_vec_.size(); ++i) { this->blob_bottom_vec_[i]->Reshape(bottom_shape); filler.Fill(this->blob_bottom_vec_[i]); } LayerParameter layer_param; ConvolutionParameter* convolution_param = layer_param.mutable_convolution_param(); convolution_param->set_num_output(18); convolution_param->set_bias_term(false); convolution_param->set_group(6); convolution_param->set_kernel_h(kernel_h); convolution_param->set_kernel_w(kernel_w); convolution_param->mutable_weight_filler()->set_type("gaussian"); Blob<Dtype> weights; Blob<Dtype> top_diff; // Shape and fill weights and top_diff. bool copy_diff; bool reshape; { DeconvolutionLayer<Dtype> layer(layer_param); layer.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); top_diff.ReshapeLike(*this->blob_top_); filler.Fill(&top_diff); ASSERT_EQ(1, layer.blobs().size()); copy_diff = false; reshape = true; weights.CopyFrom(*layer.blobs()[0], copy_diff, reshape); } vector<bool> propagate_down(1, true); Blob<Dtype> result_2d; Blob<Dtype> backward_result_2d; Blob<Dtype> backward_weight_result_2d; // Test with 2D im2col { caffe_set(this->blob_top_->count(), Dtype(0), this->blob_top_->mutable_cpu_data()); caffe_set(this->blob_bottom_->count(), Dtype(0), this->blob_bottom_->mutable_cpu_diff()); caffe_set(weights.count(), Dtype(0), weights.mutable_cpu_diff()); // Do SetUp and Forward; save Forward result in result_2d. convolution_param->set_force_nd_im2col(false); DeconvolutionLayer<Dtype> layer_2d(layer_param); layer_2d.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); ASSERT_EQ(1, layer_2d.blobs().size()); copy_diff = false; reshape = false; layer_2d.blobs()[0]->CopyFrom(weights, copy_diff, reshape); layer_2d.Forward(this->blob_bottom_vec_, this->blob_top_vec_); copy_diff = false; reshape = true; result_2d.CopyFrom(*this->blob_top_, copy_diff, reshape); // Copy pre-generated top diff into actual top diff; // do Backward and save result in backward_result_2d. ASSERT_EQ(this->blob_top_->shape(), top_diff.shape()); caffe_copy(top_diff.count(), top_diff.cpu_data(), this->blob_top_->mutable_cpu_diff()); layer_2d.Backward(this->blob_top_vec_, propagate_down, this->blob_bottom_vec_); copy_diff = true; reshape = true; backward_result_2d.CopyFrom(*this->blob_bottom_, copy_diff, reshape); backward_weight_result_2d.CopyFrom(weights, copy_diff, reshape); } Blob<Dtype> result_nd; Blob<Dtype> backward_result_nd; Blob<Dtype> backward_weight_result_nd; // Test with ND im2col { caffe_set(this->blob_top_->count(), Dtype(0), this->blob_top_->mutable_cpu_data()); caffe_set(this->blob_bottom_->count(), Dtype(0), this->blob_bottom_->mutable_cpu_diff()); caffe_set(weights.count(), Dtype(0), weights.mutable_cpu_diff()); // Do SetUp and Forward; save Forward result in result_nd. convolution_param->set_force_nd_im2col(true); DeconvolutionLayer<Dtype> layer_nd(layer_param); layer_nd.SetUp(this->blob_bottom_vec_, this->blob_top_vec_); ASSERT_EQ(1, layer_nd.blobs().size()); copy_diff = false; reshape = false; layer_nd.blobs()[0]->CopyFrom(weights, copy_diff, reshape); layer_nd.Forward(this->blob_bottom_vec_, this->blob_top_vec_); copy_diff = false; reshape = true; result_nd.CopyFrom(*this->blob_top_, copy_diff, reshape); // Copy pre-generated top diff into actual top diff; // do Backward and save result in backward_result_nd. ASSERT_EQ(this->blob_top_->shape(), top_diff.shape()); caffe_copy(top_diff.count(), top_diff.cpu_data(), this->blob_top_->mutable_cpu_diff()); layer_nd.Backward(this->blob_top_vec_, propagate_down, this->blob_bottom_vec_); copy_diff = true; reshape = true; backward_result_nd.CopyFrom(*this->blob_bottom_, copy_diff, reshape); backward_weight_result_nd.CopyFrom(weights, copy_diff, reshape); } ASSERT_EQ(result_nd.count(), result_2d.count()); for (int i = 0; i < result_2d.count(); ++i) { EXPECT_EQ(result_2d.cpu_data()[i], result_nd.cpu_data()[i]); } ASSERT_EQ(backward_result_nd.count(), backward_result_2d.count()); for (int i = 0; i < backward_result_2d.count(); ++i) { EXPECT_EQ(backward_result_2d.cpu_diff()[i], backward_result_nd.cpu_diff()[i]); } ASSERT_EQ(backward_weight_result_nd.count(), backward_weight_result_2d.count()); for (int i = 0; i < backward_weight_result_2d.count(); ++i) { EXPECT_EQ(backward_weight_result_2d.cpu_diff()[i], backward_weight_result_nd.cpu_diff()[i]); } }