long bottom(const rectangle& r) { return r.bottom(); }
long top(const rectangle& r) { return r.top(); }
long right(const rectangle& r) { return r.right(); }
vec2 getCenter()const { return bounds.center(); };
long left(const rectangle& r) { return r.left(); }
/* This function mimics the priority PROM/circuit on the pcb. It takes the tilemaps & sprite bitmaps as inputs, and outputs a final pixel based on alpha & priority values. Rendering sprites to temporary bitmaps is the only reasonable way to implement proper priority & blending support - it can't be done in-place on the final framebuffer without a lot of support bitmaps. */ void nslasher_state::mixDualAlphaSprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx0, gfx_element *gfx1, int mixAlphaTilemap) { const pen_t *pens = m_deco_ace->pens(); const pen_t *pal0 = &pens[gfx0->colorbase()]; const pen_t *pal1 = &pens[gfx1->colorbase()]; const pen_t *pal2 = &pens[m_gfxdecode->gfx((m_pri & 1) ? 1 : 2)->colorbase()]; bitmap_ind16& sprite0_mix_bitmap = m_sprgen[0]->get_sprite_temp_bitmap(); bitmap_ind16& sprite1_mix_bitmap = m_sprgen[1]->get_sprite_temp_bitmap(); /* Mix sprites into main bitmap, based on priority & alpha */ for (int y = cliprect.top(); y <= cliprect.bottom(); y++) { uint8_t* tilemapPri = &screen.priority().pix8(y); uint16_t* sprite0 = &sprite0_mix_bitmap.pix16(y); uint16_t* sprite1 = &sprite1_mix_bitmap.pix16(y); uint32_t* destLine = &bitmap.pix32(y); uint16_t* alphaTilemap = &m_tilemap_alpha_bitmap->pix16(y); for (int x = cliprect.left(); x <= cliprect.right(); x++) { uint16_t const priColAlphaPal0 = sprite0[x]; uint16_t const priColAlphaPal1 = sprite1[x]; uint16_t const pri0 = (priColAlphaPal0 & 0x6000) >> 13; uint16_t const pri1 = (priColAlphaPal1 & 0x6000) >> 13; uint16_t const col0 = (((priColAlphaPal0 & 0x1f00) >> 8) % gfx0->colors()) * gfx0->granularity(); uint16_t const col1 = (((priColAlphaPal1 & 0x0f00) >> 8) % gfx1->colors()) * gfx1->granularity(); uint16_t const alpha1 = priColAlphaPal1 & 0x8000; // Apply sprite bitmap 0 according to priority rules if ((priColAlphaPal0 & 0xff) != 0) { /* Sprite 0 priority rules: 0 = Sprite above all layers 1 = Sprite under top playfield 2 = Sprite under top two playfields 3 = Sprite under all playfields */ if ((pri0 & 0x3) == 0 || (pri0 & 0x3) == 1 || ((pri0 & 0x3) == 2 && mixAlphaTilemap)) // Spri0 on top of everything, or under alpha playfield { destLine[x] = pal0[(priColAlphaPal0 & 0xff) + col0]; } else if ((pri0 & 0x3) == 2) // Spri0 under top playfield { if (tilemapPri[x] < 4) destLine[x] = pal0[(priColAlphaPal0 & 0xff) + col0]; } else // Spri0 under top & middle playfields { if (tilemapPri[x] < 2) destLine[x] = pal0[(priColAlphaPal0 & 0xff) + col0]; } } // Apply sprite bitmap 1 according to priority rules if ((priColAlphaPal1 & 0xff) != 0) { // Apply alpha for this pixel based on Ace setting if (alpha1) { /* Alpha rules: Pri 0 - Over all tilemaps, but under sprite 0 pri 0, pri 1, pri 2 Pri 1 - Pri 2 - Pri 3 - */ /* Alpha values are tied to ACE ram... */ //int alpha = m_deco_ace->get_alpha(((priColAlphaPal1 & 0xf0) >> 4) / 2); //if (alpha < 0) // alpha = 0; /* I don't really understand how object ACE ram is really hooked up, the only obvious place in Night Slashers is the stagecoach in level 2 */ if (pri1 == 0 && (((priColAlphaPal0 & 0xff) == 0 || ((pri0 & 0x3) != 0 && (pri0 & 0x3) != 1 && (pri0 & 0x3) != 2)))) { if ((m_pri & 1) == 0 || ((m_pri & 1) == 1 && tilemapPri[x] < 4) || ((m_pri & 1) == 1 && mixAlphaTilemap)) destLine[x] = alpha_blend_r32(destLine[x], pal1[(priColAlphaPal1 & 0xff) + col1], 0x80); } else if (pri1 == 1 && ((priColAlphaPal0 & 0xff) == 0 || ((pri0 & 0x3) != 0 && (pri0 & 0x3) != 1 && (pri0 & 0x3) != 2))) destLine[x] = alpha_blend_r32(destLine[x], pal1[(priColAlphaPal1 & 0xff) + col1], 0x80); else if (pri1 == 2) // TOdo destLine[x] = alpha_blend_r32(destLine[x], pal1[(priColAlphaPal1 & 0xff) + col1], 0x80); else if (pri1 == 3) // TOdo destLine[x] = alpha_blend_r32(destLine[x], pal1[(priColAlphaPal1 & 0xff) + col1], 0x80); } else { /* Non alpha rules: Pri 0 - Under sprite 0 pri 0, over all tilemaps */ if (pri1 == 0 && ((priColAlphaPal0 & 0xff) == 0 || ((pri0 & 0x3) != 0))) destLine[x] = pal1[(priColAlphaPal1 & 0xff) + col1]; else if (pri1 == 1) // todo destLine[x] = pal1[(priColAlphaPal1 & 0xff) + col1]; else if (pri1 == 2) // todo destLine[x] = pal1[(priColAlphaPal1 & 0xff) + col1]; else if (pri1 == 3) // todo destLine[x] = pal1[(priColAlphaPal1 & 0xff) + col1]; } } /* Optionally mix in alpha tilemap */ if (mixAlphaTilemap) { uint16_t p = alphaTilemap[x]; if (p & 0xf) { /* Alpha tilemap under top two sprite 0 priorities */ if (((priColAlphaPal0 & 0xff) == 0 || (pri0 & 0x3) == 2 || (pri0 & 0x3) == 3) && ((priColAlphaPal1 & 0xff) == 0 || (pri1 & 0x3) == 2 || (pri1 & 0x3) == 3 || alpha1)) { /* Alpha values are tied to ACE ram */ int alpha = m_deco_ace->get_alpha(0x17 + (((p & 0xf0) >> 4) / 2)); if (alpha < 0) alpha = 0; destLine[x] = alpha_blend_r32(destLine[x], pal2[p], alpha); } } } } }
UINT32 aristmk6_state::screen_update_aristmk6(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { int x,y,count; const UINT8 *blit_ram = memregion("maincpu")->base(); if(machine().input().code_pressed(KEYCODE_Z)) m_test_x++; if(machine().input().code_pressed(KEYCODE_X)) m_test_x--; if(machine().input().code_pressed(KEYCODE_A)) m_test_y++; if(machine().input().code_pressed(KEYCODE_S)) m_test_y--; if(machine().input().code_pressed(KEYCODE_Q)) m_start_offs+=0x2000; if(machine().input().code_pressed(KEYCODE_W)) m_start_offs-=0x2000; if(machine().input().code_pressed(KEYCODE_E)) m_start_offs++; if(machine().input().code_pressed(KEYCODE_R)) m_start_offs--; if(machine().input().code_pressed_once(KEYCODE_L)) m_type^=1; popmessage("%d %d %04x %d",m_test_x,m_test_y,m_start_offs,m_type); bitmap.fill(m_palette->black_pen(), cliprect); count = (m_start_offs); for(y=0;y<m_test_y;y++) { for(x=0;x<m_test_x;x++) { if(m_type) { UINT16 vram; int r,g,b; vram = blit_ram[count+0] | blit_ram[count+1]<<8; r = (vram & 0x001f)>>0; g = (vram & 0x07e0)>>5; b = (vram & 0xf800)>>11; r = (r << 3) | (r & 0x7); g = (g << 2) | (g & 3); b = (b << 3) | (b & 0x7); if(cliprect.contains(x, y)) bitmap.pix32(y, x) = r | g<<8 | b<<16; count+=2; } else { UINT8 color; color = blit_ram[count]; if(cliprect.contains(x, y)) bitmap.pix32(y, x) = m_palette->pen(color); count++; } } }
int main(int argc, char** argv) { try { command_line_parser parser; parser.add_option("h","Displays this information."); parser.add_option("v","Display version."); parser.set_group_name("Creating XML files"); parser.add_option("c","Create an XML file named <arg> listing a set of images.",1); parser.add_option("r","Search directories recursively for images."); parser.add_option("convert","Convert foreign image Annotations from <arg> format to the imglab format. " "Supported formats: pascal-xml, pascal-v1, idl.",1); parser.set_group_name("Viewing XML files"); parser.add_option("tile","Chip out all the objects and save them as one big image called <arg>.",1); parser.add_option("size","When using --tile or --cluster, make each extracted object contain " "about <arg> pixels (default 8000).",1); parser.add_option("l","List all the labels in the given XML file."); parser.add_option("stats","List detailed statistics on the object labels in the given XML file."); parser.add_option("files","List all the files in the given XML file."); parser.set_group_name("Editing/Transforming XML datasets"); parser.add_option("rename", "Rename all labels of <arg1> to <arg2>.",2); parser.add_option("parts","The display will allow image parts to be labeled. The set of allowable parts " "is defined by <arg> which should be a space separated list of parts.",1); parser.add_option("rmempty","Remove all images that don't contain non-ignored annotations and save the results to a new XML file."); parser.add_option("rmdupes","Remove duplicate images from the dataset. This is done by comparing " "the md5 hash of each image file and removing duplicate images. " ); parser.add_option("rmdiff","Set the ignored flag to true for boxes marked as difficult."); parser.add_option("rmtrunc","Set the ignored flag to true for boxes that are partially outside the image."); parser.add_option("sort-num-objects","Sort the images listed an XML file so images with many objects are listed first."); parser.add_option("sort","Alphabetically sort the images in an XML file."); parser.add_option("shuffle","Randomly shuffle the order of the images listed in an XML file."); parser.add_option("seed", "When using --shuffle, set the random seed to the string <arg>.",1); parser.add_option("split", "Split the contents of an XML file into two separate files. One containing the " "images with objects labeled <arg> and another file with all the other images. ",1); parser.add_option("add", "Add the image metadata from <arg1> into <arg2>. If any of the image " "tags are in both files then the ones in <arg2> are deleted and replaced with the " "image tags from <arg1>. The results are saved into merged.xml and neither <arg1> or " "<arg2> files are modified.",2); parser.add_option("flip", "Read an XML image dataset from the <arg> XML file and output a left-right flipped " "version of the dataset and an accompanying flipped XML file named flipped_<arg>.",1); parser.add_option("rotate", "Read an XML image dataset and output a copy that is rotated counter clockwise by <arg> degrees. " "The output is saved to an XML file prefixed with rotated_<arg>.",1); parser.add_option("cluster", "Cluster all the objects in an XML file into <arg> different clusters and save " "the results as cluster_###.xml and cluster_###.jpg files.",1); parser.add_option("ignore", "Mark boxes labeled as <arg> as ignored. The resulting XML file is output as a separate file and the original is not modified.",1); parser.add_option("rmlabel","Remove all boxes labeled <arg> and save the results to a new XML file.",1); parser.add_option("rm-other-labels","Remove all boxes not labeled <arg> and save the results to a new XML file.",1); parser.add_option("rmignore","Remove all boxes marked ignore and save the results to a new XML file."); parser.add_option("rm-if-overlaps","Remove all boxes labeled <arg> if they overlap any box not labeled <arg> and save the results to a new XML file.",1); parser.add_option("jpg", "When saving images to disk, write them as jpg files instead of png."); parser.set_group_name("Cropping sub images"); parser.add_option("resample", "Crop out images that are centered on each object in the dataset. " "The output is a new XML dataset."); parser.add_option("cropped-object-size", "When doing --resample, make the cropped objects contain about <arg> pixels (default 10000).",1); parser.add_option("min-object-size", "When doing --resample, skip objects that have fewer than <arg> pixels in them (default 1).",1); parser.add_option("crop-size", "When doing --resample, the entire cropped image will be <arg> times wider than the object (default 2.5).",1); parser.add_option("one-object-per-image", "When doing --resample, only include one non-ignored object per image (i.e. the central object)."); parser.parse(argc, argv); const char* singles[] = {"h","c","r","l","files","convert","parts","rmdiff", "rmtrunc", "rmdupes", "seed", "shuffle", "split", "add", "flip", "rotate", "tile", "size", "cluster", "resample", "min-object-size", "rmempty", "crop-size", "cropped-object-size", "rmlabel", "rm-other-labels", "rm-if-overlaps", "sort-num-objects", "one-object-per-image", "jpg", "rmignore", "sort"}; parser.check_one_time_options(singles); const char* c_sub_ops[] = {"r", "convert"}; parser.check_sub_options("c", c_sub_ops); parser.check_sub_option("shuffle", "seed"); const char* resample_sub_ops[] = {"min-object-size", "crop-size", "cropped-object-size", "one-object-per-image"}; parser.check_sub_options("resample", resample_sub_ops); const char* size_parent_ops[] = {"tile", "cluster"}; parser.check_sub_options(size_parent_ops, "size"); parser.check_incompatible_options("c", "l"); parser.check_incompatible_options("c", "files"); parser.check_incompatible_options("c", "rmdiff"); parser.check_incompatible_options("c", "rmempty"); parser.check_incompatible_options("c", "rmlabel"); parser.check_incompatible_options("c", "rm-other-labels"); parser.check_incompatible_options("c", "rmignore"); parser.check_incompatible_options("c", "rm-if-overlaps"); parser.check_incompatible_options("c", "rmdupes"); parser.check_incompatible_options("c", "rmtrunc"); parser.check_incompatible_options("c", "add"); parser.check_incompatible_options("c", "flip"); parser.check_incompatible_options("c", "rotate"); parser.check_incompatible_options("c", "rename"); parser.check_incompatible_options("c", "ignore"); parser.check_incompatible_options("c", "parts"); parser.check_incompatible_options("c", "tile"); parser.check_incompatible_options("c", "cluster"); parser.check_incompatible_options("c", "resample"); parser.check_incompatible_options("l", "rename"); parser.check_incompatible_options("l", "ignore"); parser.check_incompatible_options("l", "add"); parser.check_incompatible_options("l", "parts"); parser.check_incompatible_options("l", "flip"); parser.check_incompatible_options("l", "rotate"); parser.check_incompatible_options("files", "rename"); parser.check_incompatible_options("files", "ignore"); parser.check_incompatible_options("files", "add"); parser.check_incompatible_options("files", "parts"); parser.check_incompatible_options("files", "flip"); parser.check_incompatible_options("files", "rotate"); parser.check_incompatible_options("add", "flip"); parser.check_incompatible_options("add", "rotate"); parser.check_incompatible_options("add", "tile"); parser.check_incompatible_options("flip", "tile"); parser.check_incompatible_options("rotate", "tile"); parser.check_incompatible_options("cluster", "tile"); parser.check_incompatible_options("resample", "tile"); parser.check_incompatible_options("flip", "cluster"); parser.check_incompatible_options("rotate", "cluster"); parser.check_incompatible_options("add", "cluster"); parser.check_incompatible_options("flip", "resample"); parser.check_incompatible_options("rotate", "resample"); parser.check_incompatible_options("add", "resample"); parser.check_incompatible_options("shuffle", "tile"); parser.check_incompatible_options("sort-num-objects", "tile"); parser.check_incompatible_options("sort", "tile"); parser.check_incompatible_options("convert", "l"); parser.check_incompatible_options("convert", "files"); parser.check_incompatible_options("convert", "rename"); parser.check_incompatible_options("convert", "ignore"); parser.check_incompatible_options("convert", "parts"); parser.check_incompatible_options("convert", "cluster"); parser.check_incompatible_options("convert", "resample"); parser.check_incompatible_options("rmdiff", "rename"); parser.check_incompatible_options("rmdiff", "ignore"); parser.check_incompatible_options("rmempty", "ignore"); parser.check_incompatible_options("rmempty", "rename"); parser.check_incompatible_options("rmlabel", "ignore"); parser.check_incompatible_options("rmlabel", "rename"); parser.check_incompatible_options("rm-other-labels", "ignore"); parser.check_incompatible_options("rm-other-labels", "rename"); parser.check_incompatible_options("rmignore", "ignore"); parser.check_incompatible_options("rmignore", "rename"); parser.check_incompatible_options("rm-if-overlaps", "ignore"); parser.check_incompatible_options("rm-if-overlaps", "rename"); parser.check_incompatible_options("rmdupes", "rename"); parser.check_incompatible_options("rmdupes", "ignore"); parser.check_incompatible_options("rmtrunc", "rename"); parser.check_incompatible_options("rmtrunc", "ignore"); const char* convert_args[] = {"pascal-xml","pascal-v1","idl"}; parser.check_option_arg_range("convert", convert_args); parser.check_option_arg_range("cluster", 2, 999); parser.check_option_arg_range("rotate", -360, 360); parser.check_option_arg_range("size", 10*10, 1000*1000); parser.check_option_arg_range("min-object-size", 1, 10000*10000); parser.check_option_arg_range("cropped-object-size", 4, 10000*10000); parser.check_option_arg_range("crop-size", 1.0, 100.0); if (parser.option("h")) { cout << "Usage: imglab [options] <image files/directories or XML file>\n"; parser.print_options(cout); cout << endl << endl; return EXIT_SUCCESS; } if (parser.option("add")) { merge_metadata_files(parser); return EXIT_SUCCESS; } if (parser.option("flip")) { flip_dataset(parser); return EXIT_SUCCESS; } if (parser.option("rotate")) { rotate_dataset(parser); return EXIT_SUCCESS; } if (parser.option("v")) { cout << "imglab v" << VERSION << "\nCompiled: " << __TIME__ << " " << __DATE__ << "\nWritten by Davis King\n"; cout << "Check for updates at http://dlib.net\n\n"; return EXIT_SUCCESS; } if (parser.option("tile")) { return tile_dataset(parser); } if (parser.option("cluster")) { return cluster_dataset(parser); } if (parser.option("resample")) { return resample_dataset(parser); } if (parser.option("c")) { if (parser.option("convert")) { if (parser.option("convert").argument() == "pascal-xml") convert_pascal_xml(parser); else if (parser.option("convert").argument() == "pascal-v1") convert_pascal_v1(parser); else if (parser.option("convert").argument() == "idl") convert_idl(parser); } else { create_new_dataset(parser); } return EXIT_SUCCESS; } if (parser.option("rmdiff")) { if (parser.number_of_arguments() != 1) { cerr << "The --rmdiff option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); for (unsigned long i = 0; i < data.images.size(); ++i) { for (unsigned long j = 0; j < data.images[i].boxes.size(); ++j) { if (data.images[i].boxes[j].difficult) data.images[i].boxes[j].ignore = true; } } save_image_dataset_metadata(data, parser[0]); return EXIT_SUCCESS; } if (parser.option("rmempty")) { if (parser.number_of_arguments() != 1) { cerr << "The --rmempty option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data, data2; load_image_dataset_metadata(data, parser[0]); data2 = data; data2.images.clear(); for (unsigned long i = 0; i < data.images.size(); ++i) { bool has_label = false; for (unsigned long j = 0; j < data.images[i].boxes.size(); ++j) { if (!data.images[i].boxes[j].ignore) has_label = true; } if (has_label) data2.images.push_back(data.images[i]); } save_image_dataset_metadata(data2, parser[0] + ".rmempty.xml"); return EXIT_SUCCESS; } if (parser.option("rmlabel")) { if (parser.number_of_arguments() != 1) { cerr << "The --rmlabel option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); const auto label = parser.option("rmlabel").argument(); for (auto&& img : data.images) { std::vector<dlib::image_dataset_metadata::box> boxes; for (auto&& b : img.boxes) { if (b.label != label) boxes.push_back(b); } img.boxes = boxes; } save_image_dataset_metadata(data, parser[0] + ".rmlabel-"+label+".xml"); return EXIT_SUCCESS; } if (parser.option("rm-other-labels")) { if (parser.number_of_arguments() != 1) { cerr << "The --rm-other-labels option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); const auto labels = parser.option("rm-other-labels").argument(); // replace comma by dash to form the file name std::string strlabels = labels; std::replace(strlabels.begin(), strlabels.end(), ',', '-'); std::vector<string> all_labels = split(labels, ","); for (auto&& img : data.images) { std::vector<dlib::image_dataset_metadata::box> boxes; for (auto&& b : img.boxes) { if (std::find(all_labels.begin(), all_labels.end(), b.label) != all_labels.end()) boxes.push_back(b); } img.boxes = boxes; } save_image_dataset_metadata(data, parser[0] + ".rm-other-labels-"+ strlabels +".xml"); return EXIT_SUCCESS; } if (parser.option("rmignore")) { if (parser.number_of_arguments() != 1) { cerr << "The --rmignore option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); for (auto&& img : data.images) { std::vector<dlib::image_dataset_metadata::box> boxes; for (auto&& b : img.boxes) { if (!b.ignore) boxes.push_back(b); } img.boxes = boxes; } save_image_dataset_metadata(data, parser[0] + ".rmignore.xml"); return EXIT_SUCCESS; } if (parser.option("rm-if-overlaps")) { if (parser.number_of_arguments() != 1) { cerr << "The --rm-if-overlaps option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); const auto label = parser.option("rm-if-overlaps").argument(); test_box_overlap overlaps(0.5); for (auto&& img : data.images) { std::vector<dlib::image_dataset_metadata::box> boxes; for (auto&& b : img.boxes) { if (b.label != label) { boxes.push_back(b); } else { bool has_overlap = false; for (auto&& b2 : img.boxes) { if (b2.label != label && overlaps(b2.rect, b.rect)) { has_overlap = true; break; } } if (!has_overlap) boxes.push_back(b); } } img.boxes = boxes; } save_image_dataset_metadata(data, parser[0] + ".rm-if-overlaps-"+label+".xml"); return EXIT_SUCCESS; } if (parser.option("rmdupes")) { if (parser.number_of_arguments() != 1) { cerr << "The --rmdupes option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data, data_out; std::set<std::string> hashes; load_image_dataset_metadata(data, parser[0]); data_out = data; data_out.images.clear(); for (unsigned long i = 0; i < data.images.size(); ++i) { ifstream fin(data.images[i].filename.c_str(), ios::binary); string hash = md5(fin); if (hashes.count(hash) == 0) { hashes.insert(hash); data_out.images.push_back(data.images[i]); } } save_image_dataset_metadata(data_out, parser[0]); return EXIT_SUCCESS; } if (parser.option("rmtrunc")) { if (parser.number_of_arguments() != 1) { cerr << "The --rmtrunc option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); { locally_change_current_dir chdir(get_parent_directory(file(parser[0]))); for (unsigned long i = 0; i < data.images.size(); ++i) { array2d<unsigned char> img; load_image(img, data.images[i].filename); const rectangle area = get_rect(img); for (unsigned long j = 0; j < data.images[i].boxes.size(); ++j) { if (!area.contains(data.images[i].boxes[j].rect)) data.images[i].boxes[j].ignore = true; } } } save_image_dataset_metadata(data, parser[0]); return EXIT_SUCCESS; } if (parser.option("l")) { if (parser.number_of_arguments() != 1) { cerr << "The -l option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); print_all_labels(data); return EXIT_SUCCESS; } if (parser.option("files")) { if (parser.number_of_arguments() != 1) { cerr << "The --files option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); for (size_t i = 0; i < data.images.size(); ++i) cout << data.images[i].filename << "\n"; return EXIT_SUCCESS; } if (parser.option("split")) { return split_dataset(parser); } if (parser.option("shuffle")) { if (parser.number_of_arguments() != 1) { cerr << "The --shuffle option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); const string default_seed = cast_to_string(time(0)); const string seed = get_option(parser, "seed", default_seed); dlib::rand rnd(seed); randomize_samples(data.images, rnd); save_image_dataset_metadata(data, parser[0]); return EXIT_SUCCESS; } if (parser.option("sort-num-objects")) { if (parser.number_of_arguments() != 1) { cerr << "The --sort-num-objects option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); std::sort(data.images.rbegin(), data.images.rend(), [](const image_dataset_metadata::image& a, const image_dataset_metadata::image& b) { return a.boxes.size() < b.boxes.size(); }); save_image_dataset_metadata(data, parser[0]); return EXIT_SUCCESS; } if (parser.option("sort")) { if (parser.number_of_arguments() != 1) { cerr << "The --sort option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); std::sort(data.images.begin(), data.images.end(), [](const image_dataset_metadata::image& a, const image_dataset_metadata::image& b) { return a.filename < b.filename; }); save_image_dataset_metadata(data, parser[0]); return EXIT_SUCCESS; } if (parser.option("stats")) { if (parser.number_of_arguments() != 1) { cerr << "The --stats option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); print_all_label_stats(data); return EXIT_SUCCESS; } if (parser.option("rename")) { if (parser.number_of_arguments() != 1) { cerr << "The --rename option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); for (unsigned long i = 0; i < parser.option("rename").count(); ++i) { rename_labels(data, parser.option("rename").argument(0,i), parser.option("rename").argument(1,i)); } save_image_dataset_metadata(data, parser[0]); return EXIT_SUCCESS; } if (parser.option("ignore")) { if (parser.number_of_arguments() != 1) { cerr << "The --ignore option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } dlib::image_dataset_metadata::dataset data; load_image_dataset_metadata(data, parser[0]); for (unsigned long i = 0; i < parser.option("ignore").count(); ++i) { ignore_labels(data, parser.option("ignore").argument()); } save_image_dataset_metadata(data, parser[0]+".ignored.xml"); return EXIT_SUCCESS; } if (parser.number_of_arguments() == 1) { metadata_editor editor(parser[0]); if (parser.option("parts")) { std::vector<string> parts = split(parser.option("parts").argument()); for (unsigned long i = 0; i < parts.size(); ++i) { editor.add_labelable_part_name(parts[i]); } } editor.wait_until_closed(); return EXIT_SUCCESS; } cout << "Invalid command, give -h to see options." << endl; return EXIT_FAILURE; } catch (exception& e) { cerr << e.what() << endl; return EXIT_FAILURE; } }
int main(int argc, char** argv) { try { // make sure the user entered an argument to this program if (argc != 2) { cout << "error, you have to enter a BMP file as an argument to this program" << endl; return 1; } // Here we declare an image object that can store rgb_pixels. Note that in // dlib there is no explicit image object, just a 2D array and // various pixel types. array2d<rgb_pixel> img; // Now load the image file into our image. If something is wrong then // load_image() will throw an exception. Also, if you linked with libpng // and libjpeg then load_image() can load PNG and JPEG files in addition // to BMP files. load_image(img, argv[1]); // get the 100 strongest SURF points from the image std::vector<surf_point> sp = get_surf_points(img, 100); // create a window to display the input image and the SURF boxes. (Note that // you can zoom into the window by holding CTRL and scrolling the mouse wheel) image_window my_window(img); // Now lets draw some rectangles on top of the image so we can see where // SURF found its points. for (unsigned long i = 0; i < sp.size(); ++i) { // Pull out the info from the SURF point relevant to figuring out // where its rotated box should be. const unsigned long box_size = static_cast<unsigned long>(sp[i].p.scale*20); const double ang = sp[i].angle; const point center(sp[i].p.center); const rectangle rect = centered_rect(center, box_size, box_size); // Rotate the 4 corners of the rectangle const point p1 = rotate_point(center, rect.tl_corner(), ang); const point p2 = rotate_point(center, rect.tr_corner(), ang); const point p3 = rotate_point(center, rect.bl_corner(), ang); const point p4 = rotate_point(center, rect.br_corner(), ang); // Draw the sides of the box as red lines my_window.add_overlay(p1, p2, rgb_pixel(255,0,0)); my_window.add_overlay(p1, p3, rgb_pixel(255,0,0)); my_window.add_overlay(p4, p2, rgb_pixel(255,0,0)); my_window.add_overlay(p4, p3, rgb_pixel(255,0,0)); // Draw a line from the center to the top side so we can see how the box is oriented. // Also make this line green. my_window.add_overlay(center, (p1+p2)/2, rgb_pixel(0,255,0)); } // wait until the user closes the window before we let the program // terminate. my_window.wait_until_closed(); } catch (exception& e) { cout << "exception thrown: " << e.what() << endl; } }
void rotate_dataset(const command_line_parser& parser) { image_dataset_metadata::dataset metadata; const string datasource = parser[0]; load_image_dataset_metadata(metadata,datasource); double angle = get_option(parser, "rotate", 0); // Set the current directory to be the one that contains the // metadata file. We do this because the file might contain // file paths which are relative to this folder. set_current_dir(get_parent_directory(file(datasource))); const string file_prefix = "rotated_"+ cast_to_string(angle) + "_"; const string metadata_filename = get_parent_directory(file(datasource)).full_name() + directory::get_separator() + file_prefix + file(datasource).name(); array2d<rgb_pixel> img, temp; for (unsigned long i = 0; i < metadata.images.size(); ++i) { file f(metadata.images[i].filename); string filename = get_parent_directory(f).full_name() + directory::get_separator() + file_prefix + to_png_name(f.name()); load_image(img, metadata.images[i].filename); const point_transform_affine tran = rotate_image(img, temp, angle*pi/180); if (parser.option("jpg")) { filename = to_jpg_name(filename); save_jpeg(temp, filename,JPEG_QUALITY); } else { save_png(temp, filename); } for (unsigned long j = 0; j < metadata.images[i].boxes.size(); ++j) { const rectangle rect = metadata.images[i].boxes[j].rect; rectangle newrect; newrect += tran(rect.tl_corner()); newrect += tran(rect.tr_corner()); newrect += tran(rect.bl_corner()); newrect += tran(rect.br_corner()); // now make newrect have the same area as the starting rect. double ratio = std::sqrt(rect.area()/(double)newrect.area()); newrect = centered_rect(newrect, newrect.width()*ratio, newrect.height()*ratio); metadata.images[i].boxes[j].rect = newrect; // rotate all the object parts std::map<std::string,point>::iterator k; for (k = metadata.images[i].boxes[j].parts.begin(); k != metadata.images[i].boxes[j].parts.end(); ++k) { k->second = tran(k->second); } } metadata.images[i].filename = filename; } save_image_dataset_metadata(metadata, metadata_filename); }
int resample_dataset(const command_line_parser& parser) { if (parser.number_of_arguments() != 1) { cerr << "The --resample option requires you to give one XML file on the command line." << endl; return EXIT_FAILURE; } const size_t obj_size = get_option(parser,"cropped-object-size",100*100); const double margin_scale = get_option(parser,"crop-size",2.5); // cropped image will be this times wider than the object. const unsigned long min_object_size = get_option(parser,"min-object-size",1); const bool one_object_per_image = parser.option("one-object-per-image"); dlib::image_dataset_metadata::dataset data, resampled_data; std::ostringstream sout; sout << "\nThe --resample parameters which generated this dataset were:" << endl; sout << " cropped-object-size: "<< obj_size << endl; sout << " crop-size: "<< margin_scale << endl; sout << " min-object-size: "<< min_object_size << endl; if (one_object_per_image) sout << " one_object_per_image: true" << endl; resampled_data.comment = data.comment + sout.str(); resampled_data.name = data.name + " RESAMPLED"; load_image_dataset_metadata(data, parser[0]); locally_change_current_dir chdir(get_parent_directory(file(parser[0]))); dlib::rand rnd; const size_t image_size = std::round(std::sqrt(obj_size*margin_scale*margin_scale)); const chip_dims cdims(image_size, image_size); console_progress_indicator pbar(data.images.size()); for (unsigned long i = 0; i < data.images.size(); ++i) { // don't even bother loading images that don't have objects. if (data.images[i].boxes.size() == 0) continue; pbar.print_status(i); array2d<rgb_pixel> img, chip; load_image(img, data.images[i].filename); // figure out what chips we want to take from this image for (unsigned long j = 0; j < data.images[i].boxes.size(); ++j) { const rectangle rect = data.images[i].boxes[j].rect; if (data.images[i].boxes[j].ignore || rect.area() < min_object_size) continue; const auto max_dim = std::max(rect.width(), rect.height()); const double rand_scale_perturb = 1 - 0.3*(rnd.get_random_double()-0.5); const rectangle crop_rect = centered_rect(rect, max_dim*margin_scale*rand_scale_perturb, max_dim*margin_scale*rand_scale_perturb); const rectangle_transform tform = get_mapping_to_chip(chip_details(crop_rect, cdims)); extract_image_chip(img, chip_details(crop_rect, cdims), chip); image_dataset_metadata::image dimg; // Now transform the boxes to the crop and also mark them as ignored if they // have already been cropped out or are outside the crop. for (size_t k = 0; k < data.images[i].boxes.size(); ++k) { image_dataset_metadata::box box = data.images[i].boxes[k]; // ignore boxes outside the cropped image if (crop_rect.intersect(box.rect).area() == 0) continue; // mark boxes we include in the crop as ignored. Also mark boxes that // aren't totally within the crop as ignored. if (crop_rect.contains(grow_rect(box.rect,10)) && (!one_object_per_image || k==j)) data.images[i].boxes[k].ignore = true; else box.ignore = true; if (box.rect.area() < min_object_size) box.ignore = true; box.rect = tform(box.rect); for (auto&& p : box.parts) p.second = tform.get_tform()(p.second); dimg.boxes.push_back(box); } // Put a 64bit hash of the image data into the name to make sure there are no // file name conflicts. std::ostringstream sout; sout << hex << murmur_hash3_128bit(&chip[0][0], chip.size()*sizeof(chip[0][0])).second; dimg.filename = data.images[i].filename + "_RESAMPLED_"+sout.str()+".png"; if (parser.option("jpg")) { dimg.filename = to_jpg_name(dimg.filename); save_jpeg(chip,dimg.filename, JPEG_QUALITY); } else { save_png(chip,dimg.filename); } resampled_data.images.push_back(dimg); } } save_image_dataset_metadata(resampled_data, parser[0] + ".RESAMPLED.xml"); return EXIT_SUCCESS; }
UINT32 archimedes_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { int xstart,ystart,xend,yend; int res_x,res_y; int xsize,ysize; int calc_dxs = 0,calc_dxe = 0; const UINT8 x_step[4] = { 5, 7, 11, 19 }; /* border color */ bitmap.fill(machine().pens[0x10], cliprect); /* define X display area through BPP mode register */ calc_dxs = (m_vidc_regs[VIDC_HDSR]*2)+x_step[m_vidc_bpp_mode & 3]; calc_dxe = (m_vidc_regs[VIDC_HDER]*2)+x_step[m_vidc_bpp_mode & 3]; /* now calculate display clip rectangle start/end areas */ xstart = (calc_dxs)-m_vidc_regs[VIDC_HBSR]; ystart = (m_vidc_regs[VIDC_VDSR])-m_vidc_regs[VIDC_VBSR]; xend = (calc_dxe)+xstart; yend = m_vidc_regs[VIDC_VDER]+ystart; /* disable the screen if display params are invalid */ if(xstart > xend || ystart > yend) return 0; xsize = calc_dxe-calc_dxs; ysize = m_vidc_regs[VIDC_VDER]-m_vidc_regs[VIDC_VDSR]; { int count; int x,y,xi; UINT8 pen; static UINT8 *vram = memregion("vram")->base(); count = (0); switch(m_vidc_bpp_mode) { case 0: //1 bpp { for(y=0;y<ysize;y++) { for(x=0;x<xsize;x+=8) { pen = vram[count]; for(xi=0;xi<8;xi++) { res_x = x+xi+xstart; res_y = (y+ystart)*(m_vidc_interlace+1); if(m_vidc_interlace) { if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) bitmap.pix32(res_y, res_x) = machine().pens[(pen>>(xi))&0x1]; if (cliprect.contains(res_x, res_y+1) && (res_x) <= xend && (res_y+1) <= yend) bitmap.pix32(res_y+1, res_x) = machine().pens[(pen>>(xi))&0x1]; } else { if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) bitmap.pix32(res_y, res_x) = machine().pens[(pen>>(xi))&0x1]; } } count++; } } } break; case 3: //8 bpp { for(y=0;y<ysize;y++) { for(x=0;x<xsize;x++) { pen = vram[count]; res_x = x+xstart; res_y = (y+ystart)*(m_vidc_interlace+1); if(m_vidc_interlace) { if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) bitmap.pix32(res_y, res_x) = machine().pens[(pen&0xff)+0x100]; if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y+1) <= yend) bitmap.pix32(res_y+1, res_x) = machine().pens[(pen&0xff)+0x100]; } else { if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend) bitmap.pix32(res_y, res_x) = machine().pens[(pen&0xff)+0x100]; } count++; } } } break; } }
void mapped_surface::commit_changes(const rectangle& area, error_code& ec) noexcept { cairo_surface_mark_dirty_rectangle(_Mapped_surface.csfce, static_cast<int>(area.x()), static_cast<int>(area.y()), static_cast<int>(area.width()), static_cast<int>(area.height())); ec.clear(); }
void mapped_surface::commit_changes(const rectangle& area) { cairo_surface_mark_dirty_rectangle(_Mapped_surface.csfce, static_cast<int>(area.x()), static_cast<int>(area.y()), static_cast<int>(area.width()), static_cast<int>(area.height())); }
long width(const rectangle& r) { return r.width(); }
/* * Sprite Format * ------------------ * * Word | Bit(s) | Use * -----+-fedcba9876543210-+---------------- * 0 | --------xxxxxxxx | display y start * 0 | xxxxxxxx-------- | display y end * 2 | -------xxxxxxxxx | x position * 2 | ------x--------- | unknown (used in logicpr2, maybe just a bug?) * 2 | xxxxxx---------- | unused? * 4 | ---------xxxxxxx | width * 4 | --------x------- | is this flip y like in System 16? * 4 | -------x-------- | flip x * 4 | xxxxxxx--------- | unused? * 6 | xxxxxxxxxxxxxxxx | ROM address low bits * 8 | ----------xxxxxx | color * 8 | --------xx------ | priority * 8 | ---xxxxx-------- | ROM address high bits * 8 | xxx------------- | unused? (extra address bits for larger ROMs?) * a | ---------------- | zoomx like in System 16? * c | ---------------- | zoomy like in System 16? * e | ---------------- | */ void deniam_state::draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) { int offs; UINT8 *gfx = memregion("gfx2")->base(); for (offs = m_spriteram.bytes() / 2 - 8; offs >= 0; offs -= 8) { int sx, starty, endy, x, y, start, color, width, flipx, primask; UINT8 *rom = gfx; sx = (m_spriteram[offs + 1] & 0x01ff) + 16 * 8 - 1; if (sx >= 512) sx -= 512; starty = m_spriteram[offs + 0] & 0xff; endy = m_spriteram[offs + 0] >> 8; width = m_spriteram[offs + 2] & 0x007f; flipx = m_spriteram[offs + 2] & 0x0100; if (flipx) sx++; color = 0x40 + (m_spriteram[offs + 4] & 0x3f); primask = 8; switch (m_spriteram[offs + 4] & 0xc0) { case 0x00: primask |= 4 | 2 | 1; break; /* below everything */ case 0x40: primask |= 4 | 2; break; /* below fg and tx */ case 0x80: primask |= 4; break; /* below tx */ case 0xc0: break; /* above everything */ } start = m_spriteram[offs + 3] + ((m_spriteram[offs + 4] & 0x1f00) << 8); rom += 2 * start; for (y = starty + 1; y <= endy; y++) { int drawing = 0; int i = 0; rom += 2 * width; /* note that the first line is skipped */ x = 0; while (i < 512) /* safety check */ { if (flipx) { if ((rom[i] & 0x0f) == 0x0f) { if (!drawing) drawing = 1; else break; } else { if (rom[i] & 0x0f) { if (cliprect.contains(sx + x, y)) { if ((screen.priority().pix8(y, sx + x) & primask) == 0) bitmap.pix16(y, sx + x) = color * 16 + (rom[i] & 0x0f); screen.priority().pix8(y, sx + x) = 8; } } x++; } if ((rom[i] & 0xf0) == 0xf0) { if (!drawing) drawing = 1; else break; } else { if (rom[i] & 0xf0) { if (cliprect.contains(sx + x, y)) { if ((screen.priority().pix8(y, sx + x) & primask) == 0) bitmap.pix16(y, sx + x) = color * 16+(rom[i] >> 4); screen.priority().pix8(y, sx + x) = 8; } } x++; } i--; } else { if ((rom[i] & 0xf0) == 0xf0) { if (!drawing) drawing = 1; else break; } else { if (rom[i] & 0xf0) { if (cliprect.contains(sx + x, y)) { if ((screen.priority().pix8(y, sx + x) & primask) == 0) bitmap.pix16(y, sx + x) = color * 16 + (rom[i] >> 4); screen.priority().pix8(y, sx + x) = 8; } } x++; } if ((rom[i] & 0x0f) == 0x0f) { if (!drawing) drawing = 1; else break; } else { if (rom[i] & 0x0f) { if (cliprect.contains(sx + x, y)) { if ((screen.priority().pix8(y, sx + x) & primask) == 0) bitmap.pix16(y, sx + x) = color * 16 + (rom[i] & 0x0f); screen.priority().pix8(y, sx + x) = 8; } } x++; } i++; } } } }
long height(const rectangle& r) { return r.height(); }
bool intersection(const rectangle & r, point pos_beg, point pos_end, point& good_pos_beg, point& good_pos_end) { const int right = r.right(); const int bottom = r.bottom(); if(pos_beg.x > pos_end.x) std::swap(pos_beg, pos_end); bool good_beg = (0 <= pos_beg.x && pos_beg.x < right && 0 <= pos_beg.y && pos_beg.y < bottom); bool good_end = (0 <= pos_end.x && pos_end.x < right && 0 <= pos_end.y && pos_end.y < bottom); if(good_beg && good_end) { good_pos_beg = pos_beg; good_pos_end = pos_end; return true; } else if(pos_beg.x == pos_end.x) { if(r.x <= pos_beg.x && pos_beg.x < right) { if(pos_beg.y < r.y) { if(pos_end.y < r.y) return false; good_pos_beg.y = r.y; good_pos_end.y = (pos_end.y < bottom ? pos_end.y : bottom - 1); } else if(pos_beg.y >= bottom) { if(pos_end.y >= bottom) return false; good_pos_beg.y = bottom - 1; good_pos_end.y = (pos_end.y < r.y ? r.y : pos_end.y); } good_pos_beg.x = good_pos_end.x = r.x; return true; } return false; } else if(pos_beg.y == pos_end.y) { if(r.y <= pos_beg.y && pos_beg.y < bottom) { if(pos_beg.x < r.x) { if(pos_end.x < r.x) return false; good_pos_beg.x = r.x; good_pos_end.x = (pos_end.x < right ? pos_end.x : right - 1); } else if(pos_beg.x >= right) { if(pos_end.x >= right) return false; good_pos_beg.x = right - 1; good_pos_end.x = (pos_end.x < r.x ? r.x : pos_end.x); } good_pos_beg.y = good_pos_end.y = r.y; return true; } return false; } double m = (pos_end.y - pos_beg.y ) / double(pos_end.x - pos_beg.x); bool is_nw_to_se = (m >= 0.0); //The formulas for the line. //y = m * (x - pos_beg.x) + pos_beg.y //x = (y - pos_beg.y) / m + pos_beg.x if(!good_beg) { good_pos_beg.y = static_cast<int>(m * (r.x - pos_beg.x)) + pos_beg.y; if(r.y <= good_pos_beg.y && good_pos_beg.y < bottom) { good_pos_beg.x = r.x; } else { bool cond; int y; if(is_nw_to_se) { y = r.y; cond = good_pos_beg.y < y; } else { y = bottom - 1; cond = good_pos_beg.y > y; } if(cond) { good_pos_beg.x = static_cast<int>((y - pos_beg.y) / m) + pos_beg.x; if(r.x <= good_pos_beg.x && good_pos_beg.x < right) good_pos_beg.y = y; else return false; } else return false; } if(good_pos_beg.x < pos_beg.x) return false; } else good_pos_beg = pos_beg; if(!good_end) { good_pos_end.y = static_cast<int>(m * (right - 1 - pos_beg.x)) + pos_beg.y; if(r.y <= good_pos_end.y && good_pos_end.y < bottom) { good_pos_end.x = right - 1; } else { bool cond; int y; if(is_nw_to_se) { y = bottom - 1; cond = good_pos_end.y > y; } else { y = r.y; cond = good_pos_end.y < y; } if(cond) { good_pos_end.x = static_cast<int>((y - pos_beg.y) / m) + pos_beg.x; if(r.x <= good_pos_end.x && good_pos_end.x < right) good_pos_end.y = y; else return false; } else return false; } if(good_pos_end.x > pos_end.x) return false; } else good_pos_end = pos_end; return true; }