1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#pragma version(1) 18#pragma rs java_package_name(com.example.android.rs.sample) 19#pragma rs_fp_relaxed 20 21rs_allocation image; 22rs_allocation border_values; // float3 23rs_allocation border_coords; //int2 24 25int borderLength; 26/** 27 This describes the algorithm that uses the code 28 This takes a float2 polygon and an image and searches a best fit polygon in the image 29 30 int2 __attribute__((invoke_cpu)) findBestFit(rs_allocation poly, rs_allocation image) { 31 int search_range_width; 32 int search_range_height; 33 borderLength = rsAllocationGetDimX(poly); 34 int width = rsAllocationGetDimX(image); 35 int height = rsAllocationGetDimY(image); 36 37 border_coords = alloc_int2(borderLength, 0, 0); 38 foreach(toInt, poly , border_coords); 39 border_values = alloc_float3(borderLength, 0, 0); 40 forEach_extractBorder(border_coords , border_values); 41 42 fit = alloc_float(search_range_width, search_range_width, 0); 43 borderLength = size; 44 45 forEach_bordercorrelation(image); 46 int2 fit_pos = gfindMin(fit, cx, cy, cwidth, cheight); 47 return fit_pos; 48 } 49 50void findRegion(rs_allocation coord, rs_allocation image) { 51 borderLength = rsAllocationGetDimX(coord); 52 int width = rsAllocationGetDimX(image); 53 int height = rsAllocationGetDimY(image); 54} 55 56static int4 padRegionRect(float4 rec) { 57 int width = rec.z; 58 int height = rec.w; 59 int mWidth = (((int) (8 + width)) & ~3); // bounding rectangle that is a power of 8 big 60 int mHeight = (((int) (8 + height)) & ~3); 61 int4 out = {(int)(rec.x - 1 ),(int)(rec.y - 1), width, height}; 62 return out; 63} 64 65 66*/ 67 68 69static float4 gcalcBounds(rs_allocation xy) { 70 int len = rsAllocationGetDimX(xy); 71 float2 min_xy = rsGetElementAt_float(xy, 0); 72 float2 max_xy = min_xy; 73 for (int i = 0; i < len; i += 2) { 74 float2 v = rsGetElementAt_float2(xy, i); 75 min_xy = min(min_xy, v); 76 max_xy = max(max_xy, v); 77 } 78 max_xy-=min_xy; 79 float4 out = {min_xy.x, min_xy.y, max_xy.x, max_xy.y}; 80 return out; 81} 82 83void calcBounds(rs_allocation xy, rs_allocation rect) { 84 float4 r = gcalcBounds(xy); 85 rsSetElementAt_float2(rect, r.xy, 0); 86 rsSetElementAt_float2(rect, r.zw, 1); 87} 88 89 90float3 __attribute__((kernel))extractBorder(int2 in) { 91 return convert_float3(rsGetElementAt_uchar4(image, in.x, in.y).xyz); 92} 93 94int2 __attribute__((kernel)) toInt(float2 in) { 95 int2 out = {(int)in.x, (int) in.y}; 96 return out; 97} 98 99 100static int2 gfindMin(rs_allocation fit, int cx, int cy, int cwidth, int cheight) { 101 int w = rsAllocationGetDimX(fit); 102 int h = rsAllocationGetDimY(fit); 103 float minFit = rsGetElementAt_float(fit, 0, 0); 104 int2 fit_pos = {0, 0}; 105 int reg_minx = cx; 106 int reg_miny = cy; 107 int mWidth = cwidth; 108 int mHeight = cheight; 109 int reg_width = mWidth; 110 int reg_height = mHeight; 111 int reg_maxx = reg_minx + mWidth; 112 int reg_maxy = reg_miny + mHeight; 113 for (int y = 0; y < h - mHeight; y++) { 114 115 for (int x = 0; x < w - mWidth; x++) { 116 if (!(x > reg_maxx || x + reg_width < reg_minx || y > reg_maxy 117 || y + reg_height < reg_miny)) { 118 continue; 119 } 120 float v = rsGetElementAt_float(fit, x, y); 121 if (v < minFit) { 122 minFit = v; 123 fit_pos.x = x; 124 fit_pos.y = y; 125 } 126 } 127 } 128 129 return fit_pos; 130} 131 132void findMin(rs_allocation fit, rs_allocation fit_max,int cx, int cy, int cwidth, int cheight) { 133 int2 fit_pos = gfindMin(fit, cx, cy, cwidth, cheight); 134 rsSetElementAt_int2(fit_max, fit_pos, 0); 135} 136 137int imagePosX; 138int imagePosY; 139 140float __attribute__((kernel)) bordercorrelation(uint32_t x, uint32_t y) { 141 float sum = 0; 142 int dx = x-imagePosX; 143 int dy = y-imagePosY; 144 for(int i = 0 ; i < borderLength; i++) { 145 int2 coord = rsGetElementAt_int2(border_coords, i); 146 float3 orig = convert_float3(rsGetElementAt_uchar4(image, coord.x + dx, coord.y + dy).xyz); 147 float3 candidate = rsGetElementAt_float3(border_values, i).xyz; 148 sum += distance(orig, candidate); 149 } 150 return sum; 151} 152 153