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