Rắn hình ảnh đói - Lỗ số 3


25

Lỗ số 1

Joe con rắn đang đói.

Anh ấy ăn hình ảnh, một pixel mỗi lần.

Anh ấy thực sự thích các pixel sáng.

Các thách thức

Chương trình Joe ăn các pixel sáng nhất mà anh ta có thể tìm thấy, với điều kiện anh ta chỉ có thể di chuyển lên, xuống, sang trái hoặc phải.

Thông số kỹ thuật

  • Joe phải bắt đầu ở pixel trên bên trái của hình ảnh.
  • Joe chỉ có thể di chuyển theo chiều ngang hoặc chiều dọc bằng 1 mỗi lần di chuyển
  • Joe chỉ có đủ thời gian để di chuyển 1/3 lượng pixel trong ảnh (1/3 số lần di chuyển bằng pixel). Nếu số lượng pixel không phải là bội số của 3, hãy làm tròn xuống số nguyên gần nhất.
  • Joe có thể băng qua con đường của mình, mặc dù nó được tính là 0 độ sáng
  • Độ sáng dựa trên tổng của r, g và b, vì vậy rgb (0,0,0) có độ sáng bằng 0 trong khi rgb (255,255,255) có độ sáng tối đa.

Đầu vào

Bạn có thể nhập hình ảnh theo cách bạn muốn.

Đầu ra

  • một hình ảnh hiển thị kết quả cuối cùng của hình ảnh của bạn (với các pixel bị ăn đen).
  • Lượng độ sáng đã ăn (vui lòng chỉ định phạm vi trong câu trả lời của bạn)

Chấm điểm

Chương trình của bạn sẽ được xếp loại vào:

  • Độ sáng trung bình của pixel Joe ăn / Độ sáng trung bình của pixel trong ảnh *

* bạn có thể mã hóa cái này trong chương trình của bạn

Tổng số điểm của bạn sẽ là điểm trung bình của các điểm cho các hình ảnh sau:

Hình ảnh thử nghiệm:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

http://upload.wikidia.org/wikipedia/en/thumb/f/f4/The_Scream.jpg/800px-The_Scream.jpg

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


3
Thực tế Markdown vui vẻ - Bạn có thể biến hình ảnh thành liên kết đến bản gốc của chúng : [![image description](SE URL for downsized image)](URL for original image).
Sở thích của Calvin

1
Có thể là một ý tưởng để yêu cầu mọi người đưa hình ảnh "ăn" vào câu trả lời của họ.
Nathaniel

Câu trả lời:


16

C ++, Điểm: 1.42042 1.46766

Đây thực chất là một phiên bản phức tạp hơn một chút của hai giải pháp hiện có: Trong bốn động tác có thể, nó chọn một giải pháp tối đa hóa độ sáng. Tuy nhiên, thay vì chỉ nhìn vào độ sáng của pixel mục tiêu, nó nhìn vào tổng độ sáng của pixel trong vùng lân cận của pixel mục tiêu, trong đó các pixel ở gần mục tiêu có trọng lượng lớn hơn.

EDIT: Sử dụng độ sáng phi tuyến trong tính toán lân cận giúp cải thiện điểm số một chút.

Biên dịch với g++ joe.cpp -ojoe -std=c++11 -O3 -lcairo. Yêu cầu cairo.

Chạy với joe <image-file> [<radius>]. <image-file>là hình ảnh PNG đầu vào. <radius>(đối số tùy chọn) là bán kính của vùng lân cận tổng, tính bằng pixel (nhỏ hơn nhanh hơn, lớn hơn (đại khái) tốt hơn.) Xuất ra điểm số và hình ảnh được đặt tên out.<image-file>.

#include <cairo/cairo.h>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <string>

using namespace std;

int main(int argc, const char* argv[]) {
    auto* img = cairo_image_surface_create_from_png(argv[1]);
    int width = cairo_image_surface_get_width(img),
        height = cairo_image_surface_get_height(img),
        stride = cairo_image_surface_get_stride(img);
    unsigned char* data = cairo_image_surface_get_data(img);

    double* brightness = new double[width * height];
    double total_brightness = 0;
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            const unsigned char* p = data + stride * y + 4 * x;
            total_brightness += brightness[y * width + x] = p[0] + p[1] + p[2];
        }
    }

    const int r = argc > 2 ? stoi(argv[2]) : 64, R = 2 * r + 1;
    double* weight = new double[R * R];
    for (int y = -r; y <= r; ++y) {
        for (int x = -r; x <= r; ++x)
            weight[R * (y + r) + (x + r)] = 1.0 / (x*x + y*y + 1);
    }

    auto neighborhood = [&] (int x, int y) {
        double b = 0;
        int x1 = max(x - r, 0), x2 = min(x + r, width - 1);
        int y1 = max(y - r, 0), y2 = min(y + r, height - 1);
        for (int v = y1; v <= y2; ++v) {
            const double *B = brightness + width * v + x1;
            const double *W = weight + R * (v - (y - r)) + (x1 - (x - r));
            for (int u = x1; u <= x2; ++u, ++B, ++W)
                b += (*W) * (*B) * (*B);
        }
        return b;
    };

    int n = (2 * width * height + 3) / 6;
    int x = 0, y = 0;
    double path_brightness = 0;
    int O[][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
    for (int i = 0; i < n; ++i) {
        if (i % 1000 == 0) cerr << (200 * i + n) / (2 * n) << "%\r";

        path_brightness += brightness[width * y + x]; brightness[width * y + x] = 0;
        unsigned char* p = data + stride * y + 4 * x;
        p[0] = p[1] = 16 * i % 255; p[2] = 0;

        auto O_end = partition(begin(O), end(O), [&] (const int* o) {
            return x + o[0] >= 0 && x + o[0] < width &&
                   y + o[1] >= 0 && y + o[1] < height;
        });
        const int* o_max; double o_max_neighborhood = -1;
        for (auto o = O; o != O_end; ++o) {
            double o_neighborhood = neighborhood(x + (*o)[0], y + (*o)[1]);
            if (o_neighborhood > o_max_neighborhood)
                o_max = *o, o_max_neighborhood = o_neighborhood;
        }
        x += o_max[0]; y += o_max[1];
    }

    cout << (path_brightness * width * height) / (n * total_brightness) << endl;

    cairo_surface_write_to_png(img, (string("out.") + argv[1]).c_str());

    delete []brightness;
    delete []weight;
    cairo_surface_destroy(img);
}

Các kết quả

Bridge    1.39945
Balls     1.77714
Scream    1.38349
Fractal   1.31727
Vortex    1.66493
Tornado   1.26366
-----------------
Average   1.46766

Cầu Những quả bóng Hét lên Fractal Xoáy Vòi rồng

Thêm kẹo mắt

Hoạt hình xoáy Hoạt hình lốc xoáy


Tôi vừa thử chương trình của bạn trên một số hình ảnh mẫu của riêng tôi và một bức ảnh chỉ có rất nhiều màu đen xung quanh điểm bắt đầu, và ở đó chương trình của bạn gặp sự cố do lambda hàng xóm trả lại NaN.
PlasmaHH

@PlasmaHH Tâm chia sẻ hình ảnh vi phạm?
Ell

Tôi đã cho nó ăn hình ảnh kỳ nghỉ ... 400x400 màu đen thuần túy cũng "lừa".
PlasmaHH

@PlasmaHH Chà, một hình ảnh hoàn toàn đen có điểm số không xác định, nó bằng 0, sẽ là NaN. Tuy nhiên, điều đó không ảnh hưởng đến tính toán lân cận hoặc làm hỏng chương trình (mặc dù điều này có thể phụ thuộc vào môi trường dấu phẩy động.)
Ell

Hãy xem con trỏ o_max if (o_neighborhood > o_max_neighborhood) o_max = *o, o_max_neighborhood = o_neighborhood;chỉ mã này đặt nó. tuy nhiên do nan liên quan, so sánh luôn luôn sai, do đó o_max không bao giờ được đặt và được sử dụng chưa được khởi tạo.
PlasmaHH

7

Python 3, điểm = 1,57

Đầu tiên con rắn của chúng ta di chuyển hình ảnh tạo ra các đường thẳng đứng với khoảng cách bằng nhau.

một

Chúng ta có thể mở rộng con rắn này bằng cách lấy hai điểm cạnh nhau theo một đường thẳng đứng và tạo một vòng lặp có điểm cuối là chúng.

|      |
|  =>  +----+
|      +----+
|      |

Chúng tôi sắp xếp các điểm thành các cặp và với mỗi cặp chúng tôi lưu trữ kích thước và giá trị độ sáng trung bình của vòng lặp mang lại độ sáng trung bình lớn nhất.

Ở mỗi bước, chúng tôi chọn cặp có giá trị cao nhất mở rộng vòng lặp của nó để đạt được độ sáng trung bình tối đa trên phần mở rộng và tính toán kích thước vòng tối ưu mới và giá trị độ sáng cho cặp.

Chúng tôi lưu trữ các bộ ba (giá trị, kích thước, point_ Pair) trong cấu trúc heap được sắp xếp theo giá trị để chúng tôi có thể loại bỏ phần tử lớn nhất (trong O (1)) và thêm một phần được sửa đổi mới (trong O (log n)) một cách hiệu quả.

Chúng tôi dừng lại khi đạt đến giới hạn số pixel và con rắn đó sẽ là con rắn cuối cùng.

Khoảng cách giữa các đường thẳng đứng có rất ít ảnh hưởng đến kết quả, do đó, 40 pixel không đổi được chọn.

Các kết quả

swirl    1.33084397946
chaos    1.76585674741
fractal  1.49085737611
bridge   1.42603926741
balls    1.92235115238
scream   1.48603818637
----------------------
average  1.57033111819

một một một một một một

Lưu ý: hình ảnh "The Scream" ban đầu không có sẵn nên tôi đã sử dụng một hình ảnh "The Scream" khác với độ phân giải tương tự.

Gif hiển thị quá trình mở rộng con rắn trên hình ảnh "xoáy":

một

Mã này lấy một (hoặc nhiều không gian được phân tách) tên tệp từ stdin và ghi hình ảnh con rắn thu được vào tệp png và in điểm số ra thiết bị xuất chuẩn.

from PIL import Image
import numpy as np
import heapq as hq

def upd_sp(p,st):
    vs,c=0,0
    mv,mp=-1,0
    for i in range(st,gap):
        if p[1]+i<h:
            vs+=v[p[0],p[1]+i]+v[p[0]+1,p[1]+i]
            c+=2
            if vs/c>mv:
                mv=vs/c
                mp=i
    return (-mv,mp)

mrl=[]
bf=input().split()

for bfe in bf:
    mr,mg=0,0    
    for gap in range(40,90,1500):

        im=Image.open(bfe)
        im_d=np.asarray(im).astype(int)

        v=im_d[:,:,0]+im_d[:,:,1]+im_d[:,:,2]

        w,h=v.shape

        fp=[]
        sp=[]
        x,y=0,0
        d=1

        go=True
        while go:
            if 0<=x+2*d<w:
                fp+=[(x,y)]
                fp+=[(x+d,y)]
                sp+=[(x-(d<0),y)]
                x+=2*d
                continue
            if y+gap<h:
                for k in range(gap):
                    fp+=[(x,y+k)]
                y+=gap
                d=-d
                continue
            go=False

        sh=[]
        px=im.load()

        pl=[]

        for p in fp:
            pl+=[v[p[0],p[1]]]
            px[p[1],p[0]]=(0,127,0)   

        for p in sp:
            mv,mp=upd_sp(p,1)
            if mv<=0:
                hq.heappush(sh,(mv,1,mp+1,p))

        empty=False
        pleft=h*w//3
        pleft-=len(fp)
        while pleft>gap*2 and not empty:

            if len(sh)>0:
                es,eb,ee,p=hq.heappop(sh)
            else:
                empty=True
            pleft-=(ee-eb)*2

            mv,mp=upd_sp(p,ee)
            if mv<=0:
                hq.heappush(sh,(mv,ee,mp+1,p))    

            for o in range(eb,ee):
                pl+=[v[p[0],p[1]+o]]
                pl+=[v[p[0]+1,p[1]+o]]
                px[p[1]+o,p[0]]=(0,127,0)   
                px[p[1]+o,p[0]+1]=(0,127,0)

        pl+=[0]*pleft

        sb=sum(pl)/len(pl)
        ob=np.sum(v)/(h*w)

        im.save(bfe[:-4]+'snaked.png')

        if sb/ob>mr:
            mr=sb/ob
            mg=gap

    print(bfe,mr)
    mrl+=[mr]

print(sum(mrl)/len(mrl))

5

Python 2 (điểm: 0,0797116)

Chỉ cần một thuật toán tham lam rất đơn giản và ngây thơ để có được quả bóng lăn.

#!/usr/bin/python

from PIL import Image

OFFSETS = [(-1, 0), (0, -1), (1, 0), (0, 1)]
def test_img(filename):
    img = Image.open(filename)

    joe, eaten = (0, 0), []
    img_w, img_h = img.size
    all_pixels = [
        sum(img.getpixel((x, y)))
        for x in xrange(img_w)
        for y in xrange(img_h)
    ]
    total_brightness = float(sum(all_pixels)) / len(all_pixels)

    for _ in xrange(0, (img_w*img_h)/3):
        max_offset, max_brightness = (0, 0), 0
        for o in OFFSETS:
            try:
                brightness = sum(img.getpixel((joe[0] + o[0], joe[1] + o[1])))
            except IndexError:
                brightness = -1
            if brightness >= max_brightness:
                max_offset = o
                max_brightness = brightness

        joe = (joe[0] + max_offset[0], joe[1] + max_offset[1])
        eaten.append(max_brightness)
        img.putpixel(joe, (0, 0, 0))

    eaten_brightness = float(sum(eaten)) / len(eaten)
    print('%d of %d (score %f)' % (eaten_brightness, total_brightness, eaten_brightness / total_brightness))
    img.show()

test_img('img0.jpg')
test_img('img1.png')
test_img('img2.jpg')
test_img('img3.jpg')
test_img('img4.jpg')

Đầu ra:

llama@llama:~/Code/python/ppcg40069hungrysnake$ ./hungrysnake.py 
15 of 260 (score 0.060699)
9 of 132 (score 0.074200)
16 of 300 (score 0.055557)
4 of 369 (score 0.010836)
79 of 400 (score 0.197266)

1
Tôi nghĩ rằng điểm số của bạn là tắt. Đó là mức độ sáng trung bình của Joe ăn trên độ sáng trung bình cho toàn bộ hình ảnh ... Một Joe ngẫu nhiên sẽ nhận được số điểm xấp xỉ 1.
Stretch Maniac

@StretchManiac Hmm, tôi không thấy có gì sai cả. sum of brightnesses of eaten pixels / amount of eaten pixelsđúng công thức, đúng không? Có lẽ nó chỉ là một thuật toán thực sự khủng khiếp;)
Doorknob

@Doorknob đó làThe average brightness of pixels Joe eats / The average brightness of the pixels in the picture*
hmatt1

Đối với màu cam và đen (không phải màu xanh), tôi có độ sáng trung bình là 68,0846 ... Điều này dường như không phù hợp với bất kỳ màu nào của bạn. Có lẽ tổng (getPixel (...)) không trả lại những gì bạn muốn? (Tôi là một người mới chơi trăn). BTW, có 6 hình ảnh, nhưng bạn chỉ có 5 đầu ra. Bạn cũng có thể dán nhãn hình ảnh nào đó?
Căng thẳng điên cuồng

@StretchManiac Bạn tính toán độ sáng của bạn như thế nào? Tôi chỉ tính tổng các giá trị R, G và B. Xin lỗi, tôi đã bỏ lỡ cái thứ hai đến cuối cùng (cái mà bạn đã đề cập trong bình luận của bạn, tôi nghĩ vậy). Tôi sẽ thêm nó vào buổi sáng (tôi phải đi ngủ bây giờ).
Doorknob

5

Java (điểm: 0,6949)

Một thuật toán đơn giản ăn pixel sáng nhất trong số bốn pixel xung quanh pixel hiện tại. Trong trường hợp hòa, pixel ăn là ngẫu nhiên, dẫn đến điểm số khác nhau và kết quả hình ảnh mỗi lần thực hiện. Như vậy, điểm số dưới đây là trung bình hơn 50 lần thực hiện trên mỗi hình ảnh.

Để chạy nó, hoặc chỉnh sửa ba đối số (hiện là hằng số lớp) trong nguồn, hoặc vượt qua chúng thông qua dòng lệnh theo hình thức java HungryImageSnake <source> <iterations> <printScores>nơi <source>là file nguồn của hình ảnh để ăn, <iterations>là số lần ăn ảnh (chụp điểm trung bình và lưu điểm tốt nhất trong tất cả các lần lặp) và <printScores>đúng khi in điểm của mỗi lần lặp hoặc sai thành không.

import javax.imageio.ImageIO;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;

public class HungryImageSnake {

    private static final String SOURCE = "tornado.jpg";
    private static final int ITERATIONS = 50;
    private static final boolean PRINT_SCORES = true;

    public static void main(String[] args) {
        try {
            String source = args.length > 0 ? args[0] : SOURCE;
            int iterations = args.length > 1 ? Integer.parseInt(args[1]) : ITERATIONS;
            boolean printScores = args.length > 2 ? Boolean.parseBoolean(args[2]) : PRINT_SCORES;

            System.out.printf("Reading '%s'...%n", source);
            System.out.printf("Performing %d meals...%n", iterations);
            BufferedImage image = ImageIO.read(new File(source));
            double totalScore = 0;
            double bestScore = 0;
            BufferedImage bestImage = null;
            for (int i = 0; i < iterations; i++) {
                HungryImageSnake snake = new HungryImageSnake(image);
                while (snake.isHungry()) {
                    snake.eat();
                }
                double score = snake.getScore();
                if (printScores) {
                    System.out.printf("    %d: score of %.4f%n", i + 1, score);
                }
                totalScore += score;
                if (bestImage == null || score > bestScore) {
                    bestScore = score;
                    bestImage = snake.getImage();
                }
            }
            System.out.printf("Average score: %.4f%n", totalScore / iterations);
            String formattedScore = String.format("%.4f", bestScore);
            String output = source.replaceFirst("^(.*?)(\\.[^.]+)?$", "$1-b" + formattedScore + "$2");
            ImageIO.write(bestImage, source.substring(source.lastIndexOf('.') + 1), new File(output));
            System.out.printf("Wrote best image (score: %s) to '%s'.%n", bestScore, output);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private int x;
    private int y;
    private int movesLeft;
    private int maximumMoves;
    private double eatenAverageBrightness;
    private double originalAverageBrightness;
    private BufferedImage image;

    public HungryImageSnake(BufferedImage image) {
        this.image = copyImage(image);
        int size = image.getWidth() * image.getHeight();
        this.maximumMoves = size / 3;
        this.movesLeft = this.maximumMoves;
        int totalBrightness = 0;
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                totalBrightness += getBrightnessAt(x, y);
            }
        }
        this.originalAverageBrightness = totalBrightness / (double) size;
    }

    public BufferedImage getImage() {
        return image;
    }

    public double getEatenAverageBrightness() {
        return eatenAverageBrightness;
    }

    public double getOriginalAverageBrightness() {
        return originalAverageBrightness;
    }

    public double getScore() {
        return eatenAverageBrightness / originalAverageBrightness;
    }

    public boolean isHungry() {
        return movesLeft > 0;
    }

    public void eat() {
        if (!isHungry()) {
            return;
        }
        int[][] options = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        shuffleArray(options); // prevent snake from getting stuck in corners
        int[] bestOption = null;
        int bestBrightness = 0;
        for (int[] option : options) {
            int optionX = this.x + option[0];
            int optionY = this.y + option[1];
            if (exists(optionX, optionY)) {
                int brightness = getBrightnessAt(optionX, optionY);
                if (bestOption == null || brightness > bestBrightness) {
                    bestOption = new int[]{ optionX, optionY };
                    bestBrightness = brightness;
                }
            }
        }

        image.setRGB(bestOption[0], bestOption[1], 0);
        this.movesLeft--;
        this.x = bestOption[0];
        this.y = bestOption[1];
        this.eatenAverageBrightness += bestBrightness / (double) maximumMoves;
    }

    private boolean exists(int x, int y) {
        return x >= 0 && x < image.getWidth() && y >= 0 && y < image.getHeight();
    }

    private int getBrightnessAt(int x, int y) {
        int rgb = image.getRGB(x, y);
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >> 8) & 0xFF;
        int b = rgb & 0xFF;
        return r + g + b;
    }

    private static <T> void shuffleArray(T[] array) {
        Random random = new Random();
        for (int i = array.length - 1; i > 0; i--) {
            int index = random.nextInt(i + 1);
            T temp = array[index];
            array[index] = array[i];
            array[i] = temp;
        }
    }

    private static BufferedImage copyImage(BufferedImage source){
        BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), source.getType());
        Graphics g = b.getGraphics();
        g.drawImage(source, 0, 0, null);
        g.dispose();
        return b;
    }
}

Điểm trung bình, bằng hình ảnh, hơn năm mươi lần lặp:

Bridge - 0.7739
Spheres - 0.5580
Scream - 0.8197
Fractal - 0.3850
Vortex - 0.9158
Tornado - 0.7172

Điểm số tốt nhất, bằng hình ảnh, qua cùng năm mươi lần lặp:

Bridge - 0.8996
Spheres - 0.8741
Scream - 0.9183
Fractal - 0.5720
Vortex - 1.1520
Tornado - 0.9281

Điểm số cao nhất chạy hình ảnh:

Cầu - 0.8996 Hình cầu - 0,8741 Hét lên - 0.9183 Fractal - 0,5720 Xoáy - 1.1520 Lốc xoáy - 0,9281

Như hiển nhiên từ các hình ảnh, chưa đến một phần ba pixel thực sự bị ăn, vì con rắn thỉnh thoảng bị mắc kẹt giữa các pixel mà nó đã ăn, tại đó nó vẫn bị mắc kẹt trong vùng chết cho đến khi sự di chuyển ngẫu nhiên của nó mang đến một phần ăn được của hình ảnh.

Ngoài ra, do các con rắn ăn lại các pixel, điểm số bị lệch xuống dưới, vì độ sáng bằng không của các pixel chết một lần nữa được đưa vào mức trung bình. Tôi hy vọng sẽ thấy điểm số cao hơn nhiều nếu thuật toán chấm điểm được sửa đổi để chỉ chia cho số lần di chuyển dẫn đến ăn pixel mới, thay vì tất cả các lần di chuyển (bao gồm cả những lần con rắn ăn một pixel giờ đã chết mà nó đã ăn trước đó ).

Tất nhiên, một cách tiếp cận tốt hơn sẽ là tạo ra một số độ sáng heuristic cho từng pixel và tìm đường dẫn của width * height / 3pixel có độ sáng trung bình cao nhất, nhưng tôi nghi ngờ cách tiếp cận này sẽ tối ưu trong thời gian chạy, đặc biệt là trên các hình ảnh lớn hơn, như số hoán vị có thể sẽ rất lớn. Tôi có thể chụp một số hình thức của phương pháp này sau đó và đăng nó trong một câu trả lời riêng nếu có.


Nếu bất cứ ai bị làm phiền bởi câu trả lời của tôi lớn như thế nào (do các hình ảnh trong đó), hãy cho tôi biết và tôi sẽ xóa các hình ảnh có lợi cho các liên kết hoặc một thay thế ít chi tiết khác. Hoặc, nếu bất cứ ai muốn bản gốc độ phân giải đầy đủ của bất kỳ hình ảnh "ăn", hãy cho tôi biết trong một nhận xét là tốt.
FThndry

4

Python 2, Điểm: 1.205

Tôi đã đưa ra một giải pháp Python nhanh một thời gian trước nhưng quên đăng nó. Nó đây rồi Nó tìm thấy các khối phong phú nhất trong hình ảnh, sau đó di chuyển đến từng khối, ăn tất cả các khối tốt nhất mà nó có.

Các kết quả

bridge.jpg: 591.97866/515.41501 =                               1.14855 
BallsRender.png: 493.24711/387.80635 =                          1.27189 
Mandel_zoom_04_seehorse_tail.jpg: 792.23990/624.60579 =         1.26838 
Red_Vortex_Apophysis_Fractal_Flame.jpg: 368.26121/323.08463 =   1.13983 
The_Scream.jpg: 687.18565/555.05221 =                           1.23806
swirl.jpg: 762.89469/655.73767 =                                1.16341

AVERAGE                                                         1.205

Ảnh ví dụ

Hình ảnh cầu đã xử lý

Mã Python 2.7

from pygame.locals import *
import pygame, sys, random

fn = sys.argv[1]

screen = pygame.display.set_mode((1900,1000))
pic = pygame.image.load(fn)
pic.convert()
W,H = pic.get_size()
enough = W*H/3
screen.blit(pic, (0,0))

ORTH = [(-1,0), (1,0), (0,-1), (0,1)]
def orth(p):
    return [(p[0]+dx, p[1]+dy) for dx,dy in ORTH]

def look(p):
    x,y = p
    if 0 <= x < W and 0 <= y < H:
        return sum(pic.get_at(p))
    else:
        return -1

# index picture
locs = [(x,y) for x in range(W) for y in range(H)]
grid = dict( (p,sum(pic.get_at(p))) for p in locs )
rank = sorted( grid.values() )
median = rank[ len(rank)/2 ]
dark = dict( (k,v) for k,v in grid if v < median )
good = dict( (k,v) for k,v in grid if v > median )
pictotal = sum(rank)
picavg = 1.0 * pictotal/(W*H)
print('Indexed')

# compute zone values:
block = 16
xblocks, yblocks = (W-1)/block, (H-1)/block
zones = dict( ((zx,zy),0) for zx in range(xblocks) for zy in range(yblocks) )
for x,y in locs:
    div = (x/block, y/block)
    if div in zones:
        colsum = sum( pic.get_at((x,y)) )
        zones[div] += colsum

# choose best zones:
zonelist = sorted( (v,k) for k,v in zones.items() )
cut = int(xblocks * yblocks * 0.33)
bestzones = dict( (k,v) for v,k in zonelist[-cut:] )

# make segment paths:
segdrop = [(0,1)] * (block-1)
segpass = [(1,0)] * block
segloop = [(0,-1)] * (block-1) + [(1,0)] + [(0,1)] * (block-1)
segeat = ( segloop+[(1,0)] ) * (block/2)
segshort = [(1,0)] * 2 + ( segloop+[(1,0)] ) * (block/2 - 1)

def segtopath(path, seg, xdir):
    for dx,dy in seg:
        x,y = path[-1]
        newloc = (x+dx*xdir, y+dy)
        path.append(newloc)

# design good path:
xdir = 1
path = [(0,0)]
segtopath(path, segdrop, xdir)
shortzone = True
while True:
    x,y = path[-1]
    zone = (x/block, y/block)
    if zone in bestzones:
        if shortzone:
            seg = segshort
        else:
            seg = segeat
    else:
        seg = segpass
    segtopath(path, seg, xdir)
    shortzone = False
    # check end of x block run:
    x,y = path[-1]
    zone = (x/block, y/block)
    if not ( 0 <= x < xblocks*block ):
        del path[-1]
        segtopath(path, segdrop, xdir)
        shortzone = True
        xdir = xdir * -1
    if len(path) > enough:
        break
print('Path Found')

# show path on picture:
loc = path.pop(0)
eaten = 1
joetotal = grid[loc]
i = 0
while eaten <= enough:
    loc = path[i]
    i += 1
    pic.set_at(loc, (0,0,0))
    joetotal += grid[loc]
    eaten += 1
    if i % 1000 == 0:
        screen.blit(pic, (0,0))
        pygame.display.flip()
        for event in pygame.event.get():
            if event.type == QUIT: sys.exit(0)

# save picture and wait:
screen.blit(pic, (0,0))
pygame.display.flip()
pygame.image.save(pic, 'output/'+fn)
joeavg = 1.0 * joetotal/eaten
print '%s: %7.5f/%7.5f = %7.5f' % (fn, joeavg, picavg, joeavg/picavg)
while True:
    for event in pygame.event.get():
        if event.type == QUIT: sys.exit(0)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.