void TexturePatch::set_pixel_value(math::Vec2i pixel, math::Vec3f color) { assert(blending_mask != NULL); assert(valid_pixel(pixel)); std::copy(color.begin(), color.end(), &image->at(pixel[0], pixel[1], 0)); blending_mask->at(pixel[0], pixel[1], 0) = 128; }
math::Vec3f TexturePatch::get_pixel_value(math::Vec2f pixel) const { assert(valid_pixel(pixel)); math::Vec3f color; image->linear_at(pixel[0], pixel[1], *color); return color; }
void TextureView::export_triangle(math::Vec3f v1, math::Vec3f v2, math::Vec3f v3, std::string const & filename) const { assert(image != NULL); math::Vec2f p1 = get_pixel_coords(v1); math::Vec2f p2 = get_pixel_coords(v2); math::Vec2f p3 = get_pixel_coords(v3); assert(valid_pixel(p1) && valid_pixel(p2) && valid_pixel(p3)); Tri tri(p1, p2, p3); Rect<float> aabb = tri.get_aabb(); const int width = ceil(aabb.width()); const int height = ceil(aabb.height()); const int left = floor(aabb.min_x); const int top = floor(aabb.max_y); assert(width > 0 && height > 0); mve::image::save_png_file(mve::image::crop(image, width, height, left, top, *math::Vec3uc(255, 0, 255)), filename); }
/* TODO - label_contour is called two times; only once suffices */ AnimalExport ImgPUInt32 * msskl_difference(ann_img *aimg) { ImgPUInt32 *imcont, *immsskel, *imseed, *imperim; puint32 *seed, *cont, *perim, *pred, *label, *msskel, maxd1, maxd2, MaxD; int r,c,i,j,k,qx,qy,p,q, d1,d2, *idxlut,n; r = aimg->label->rows; c = aimg->label->cols; n = r*c; idxlut = aimg->label->lut; imcont = label_contour(aimg->img); imperim = perimeter(aimg->img); immsskel = new_img_puint32(r,c); imseed = root_map(aimg->pred); seed = imseed->data; cont = imcont->data; perim = imperim->data; msskel = immsskel->data; pred = aimg->pred->data; label = aimg->label->data; MaxD = 0; for (i=0; i<r; i++) for (j=0; j<c; j++) { p = index1(i,j,idxlut); // @@@ why eliminate the contours?? if (pred[p] != (unsigned)p) {/* Eliminates the contours and considers the side option */ maxd1 = maxd2 = 0; for (k=0; k < 4; k++) { qy = n4[k][0] + i; qx = n4[k][1] + j; if (valid_pixel(r,c,qx,qy)) { q = index1(qy,qx,idxlut); if (cont[seed[p]] == cont[seed[q]]) { // not a SKIZ d2 = label[q] - label[p]; if (d2 > (int)perim[seed[p]]-d2) d2 = (int)perim[seed[p]]-d2; if (d2 > (int)maxd2) maxd2 = (unsigned)d2; } else { // a SKIZ d1 = cont[seed[q]] - cont[seed[p]]; if (d1 > (int)maxd1) maxd1 = (unsigned)d1; } } } if (maxd1 > 0) msskel[p] = UINT_MAX; else { msskel[p] = maxd2; if (msskel[p] > MaxD) MaxD = msskel[p]; } } } for (p=0; p < n; p++) if (msskel[p] == UINT_MAX) msskel[p] = MaxD + 1; imfree_puint32(&imcont); imfree_puint32(&imperim); imfree_puint32(&imseed); return immsskel; }
void TextureView::get_face_info(math::Vec3f const & v1, math::Vec3f const & v2, math::Vec3f const & v3, ProjectedFaceInfo * face_info, Settings const & settings) const { assert(image != NULL); assert(settings.data_term != GMI || gradient_magnitude != NULL); math::Vec2f p1 = get_pixel_coords(v1); math::Vec2f p2 = get_pixel_coords(v2); math::Vec2f p3 = get_pixel_coords(v3); assert(valid_pixel(p1) && valid_pixel(p2) && valid_pixel(p3)); Tri tri(p1, p2, p3); float area = tri.get_area(); if (area < std::numeric_limits<float>::epsilon()) { face_info->quality = 0.0f; return; } std::size_t num_samples = 0; math::Vec3d colors(0.0); double gmi = 0.0; bool sampling_necessary = settings.data_term != AREA || settings.outlier_removal != NONE; if (sampling_necessary && area > 0.5f) { /* Sort pixels in ascending order of y */ while (true) if(p1[1] <= p2[1]) if(p2[1] <= p3[1]) break; else std::swap(p2, p3); else std::swap(p1, p2); /* Calculate line equations. */ float const m1 = (p1[1] - p3[1]) / (p1[0] - p3[0]); float const b1 = p1[1] - m1 * p1[0]; /* area != 0.0f => m1 != 0.0f. */ float const m2 = (p1[1] - p2[1]) / (p1[0] - p2[0]); float const b2 = p1[1] - m2 * p1[0]; float const m3 = (p2[1] - p3[1]) / (p2[0] - p3[0]); float const b3 = p2[1] - m3 * p2[0]; bool fast_sampling_possible = std::isfinite(m1) && m2 != 0.0f && std::isfinite(m2) && m3 != 0.0f && std::isfinite(m3); Rect<float> aabb = tri.get_aabb(); for (int y = std::floor(aabb.min_y); y < std::ceil(aabb.max_y); ++y) { float min_x = aabb.min_x - 0.5f; float max_x = aabb.max_x + 0.5f; if (fast_sampling_possible) { float const cy = static_cast<float>(y) + 0.5f; min_x = (cy - b1) / m1; if (cy <= p2[1]) max_x = (cy - b2) / m2; else max_x = (cy - b3) / m3; if (min_x >= max_x) std::swap(min_x, max_x); if (min_x < aabb.min_x || min_x > aabb.max_x) continue; if (max_x < aabb.min_x || max_x > aabb.max_x) continue; } for (int x = std::floor(min_x + 0.5f); x < std::ceil(max_x - 0.5f); ++x) { math::Vec3d color; const float cx = static_cast<float>(x) + 0.5f; const float cy = static_cast<float>(y) + 0.5f; if (!fast_sampling_possible && !tri.inside(cx, cy)) continue; if (settings.outlier_removal != NONE) { for (std::size_t i = 0; i < 3; i++){ color[i] = static_cast<double>(image->at(x, y, i)) / 255.0; } colors += color; } if (settings.data_term == GMI) { gmi += static_cast<double>(gradient_magnitude->at(x, y, 0)) / 255.0; } ++num_samples; } } } if (settings.data_term == GMI) { if (num_samples > 0) { gmi = (gmi / num_samples) * area; } else { double gmv1 = static_cast<double>(gradient_magnitude->linear_at(p1[0], p1[1], 0)) / 255.0; double gmv2 = static_cast<double>(gradient_magnitude->linear_at(p2[0], p2[1], 0)) / 255.0; double gmv3 = static_cast<double>(gradient_magnitude->linear_at(p3[0], p3[1], 0)) / 255.0; gmi = ((gmv1 + gmv2 + gmv3) / 3.0) * area; } } if (settings.outlier_removal != NONE) { if (num_samples > 0) { face_info->mean_color = colors / num_samples; } else { math::Vec3d c1, c2, c3; for (std::size_t i = 0; i < 3; ++i) { c1[i] = static_cast<double>(image->linear_at(p1[0], p1[1], i)) / 255.0; c2[i] = static_cast<double>(image->linear_at(p2[0], p2[1], i)) / 255.0; c3[i] = static_cast<double>(image->linear_at(p3[0], p3[1], i)) / 255.0; } face_info->mean_color = ((c1 + c2 + c3) / 3.0); } } switch (settings.data_term) { case AREA: face_info->quality = area; break; case GMI: face_info->quality = gmi; break; } }