달의 크기를 계산


19

달 미스터리의 크기

나는 달의 크기가 변한다고 들었습니다. 당신이 사랑에 있고 운이 좋으면 달의 크기는 정상적인 상황에 비해 거의 두 배입니다. 어떤 사람들은 그 이유가 렌즈 역할을하는 대기라고 말합니다. 다른 사람들은 그것이 근처의 나무와 같은 다른 물체와 비교하는 문제 일 뿐이라고 생각합니다. 어떤 설명을 읽든 그것은 매우 주관적입니다.

달 과학의 크기

좋아, 우리는 프로그래머 야, 그렇지 않니? 우리는 사실에 의존합니다. 실험은 다음과 같습니다.

  1. 시간과 조리개 설정을 수동으로 지원하는 멋진 카메라를 사용하십시오.
  2. 카메라를 최대 줌 레벨로 설정하십시오.
  3. 외출하고 달을 선명하게하고 조명이 잘되도록 최상의 설정을 감지하기 위해 달 사진을 찍습니다.
  4. 설정 기억
  5. 달이 크거나 작을 때마다 해당 설정으로 달 사진을 찍습니다.
  6. 달의 크기를 픽셀 단위로 계산

카메라가 거짓말을하지 않습니까? 밝은 픽셀을 세면 달 크기를 적어도 픽셀 단위로 효과적으로 측정 할 수 있습니다.

크기가 모든 사진에서 동일하다면 우리 뇌의 버그입니다. 크기가 다르면 추측의 여지가 있습니다

  • 달은 실제로 자랍니다 (그러나 무엇을 먹습니까?)
  • 대기 렌즈 효과가 있습니다
  • 달은 타원 곡선을 가지고 있으며 때로는 더 가깝고 때로는 더 멀어집니다.
  • ...

그러나 나는 당신의 작업이 완료 될 때까지 그것을 열어 둡니다. 물론 소프트웨어가 달 크기를 정확하게 계산할 수 있는지 미리 알고 싶습니다.

작업

달의 최적화 된 몇 장의 그림이 주어지면 달의 크기를 계산하십시오. 최적화는 다음과 같습니다. 픽셀이 검은 색 또는 흰색입니다. 사이에 아무것도 없습니다. 앤티 앨리어싱이 없습니다. 그것은 쉽지 않습니까?

주의 사항 : 달이 항상 가득 찬 것은 아닙니다. 알다시피 ... 낫입니다! 그러나 낫 모양에서도 달의 크기가 더 큽니다. 따라서 전체 크기를 계산하십시오.

  • 프로그램 stdin대신 함수를 작성하는 경우 프로그램은 PNG를 입력 (예 : 파일 이름 명령 행 인수, 파이프 라인 또는 비트 맵 객체 (표준 프레임 워크 라이브러리)으로)으로 사용합니다.
  • 프로그램은 반드시 정사각형이 아닌 적절한 입력 비트 맵 크기로 작동합니다. 150 픽셀의 최소 너비와 높이가 보장됩니다.
  • 보름달은 그림의 25 % 이상을 차지합니다.
  • 프로그램은 보름달처럼 달의 계산 된 크기를 픽셀 단위로 출력합니다.
  • 우리는 달이 완벽한 구체라고 가정합니다.
  • 정확한 크기는 항상 정수이지만 계산에서 반환하면 10 진수를 출력 할 수 있습니다.
  • 정확도는 98 %와 102 % 사이 여야합니다. (이것은 내가 성취 할 수 있다고 보장 할 수있는 것보다 추측입니다. 도달하기가 너무 어렵다고 생각되면 의견을 남겨주세요.)

업데이트 :

  • 달의 중심이 그림의 중간에있을 필요는 없습니다.
  • 최소 가시 영역은 달의 5 % 또는 총 픽셀 수의 1.25 %입니다.
  • 사진은 보름달이 이미지에 맞는 방식으로 촬영됩니다. 즉 총 픽셀 수는 달 크기의 상위 경계입니다.
  • 달이 잘 리거나 잘리지 않습니다.

샘플

원하는 경우 블렌드 파일을 사용하여 자체 샘플을 생성 할 수 있습니다 . 나는 당신을 위해 다음 그림을 만들었습니다. WhitePixelCounter.exe (.NET 필요)를 사용하여 PNG 파일의 픽셀 수를 계산 하여 이미지에 흑백 픽셀 만 포함되어 있는지 여부와 그 수를 확인할 수 있습니다.

다음 256x256 픽셀 이미지는 흰색 픽셀의 양이 다르지만 계산 된 달 크기는 16416 픽셀이어야합니다.

보름달 달 달 달 달 달

이 177x177 픽셀 이미지는 10241 픽셀을 반환해야합니다. 이미지는 기본적으로 동일하지만 이번에는 초점 거리가 다른 카메라가 사용되었습니다.

달 달 달 달 달 달

9988의 결과를 가진 정사각형 및 중심이 아닌 샘플 :

사각형이 아닌 프레임의 문 사각형이 아닌 프레임의 문 사각형이 아닌 프레임의 문 사각형이 아닌 프레임의 문 사각형이 아닌 프레임의 문

오, 지금은 참조 구현이 없으며 무언가를 구현할 수 있는지조차 알지 못합니다. 그러나 내 두뇌에는 수학적으로 해결할 수 있어야한다는 강한 믿음이 있습니다.

규칙

이것은 코드 골프입니다. 2015-03-30의 가장 짧은 코드가 승인됩니다.


9
모든 예에서 달의 중심은 그림의 중앙에있는 것으로 보입니다. 달이 항상 중심에 있다고 가정 할 수 있습니까?
Digital Trauma

1
면적의 +/- 2 % 정확도는 직경의 +/- 1 %에 해당합니다. 예 : r = 100 픽셀, 면적 = 10000 * pi; r = 101 픽셀, 면적 = 10201 * pi. 내 작은 이미지를 가지고, R 72이되어야 그러므로 = 144 거라고 다만 가능. 그러나 d = 100 미만의 이미지에서는 정확도를 충족시킬 수 없다고 생각합니다.
Level River St

@DigitalTrauma : 중앙이 중앙에있을 필요는 없습니다.
Thomas Weller

@ MartinBüttner : 보이는 최소 백분율은 달의 5 % 또는 그림의 1,25 %입니다.
Thomas Weller

@ MartinBüttner : 좋아, 질문을 업데이트하고 기본적으로 사각형이 아닌 중심 이미지를 생성하도록 블렌드 파일을 업데이트했습니다. 여기에서 모든 이미지 를 다운로드 할 수 있습니다 (* .png.zip) . 업데이트 된 픽셀 카운터 : 추가 정보를 출력하고 1.25 % 규칙을 확인합니다.
Thomas Weller

답변:


10

Mathematica 126119109 바이트

Mathematica는 이미지에서 구성 요소의 신장을 측정 할 수 있습니다. 완벽하게 대칭 인 보름달의 신장은 0에서 1까지입니다.

점점 작아지는 달은 점점 약 0.8까지 늘어납니다.

0.998 -0.788 x-0.578 x^2 `길이 늘어난 달의 충만도 (지역별)를 예측하기 위해 경험적으로 결정된 모델 (큰 사진을 기반으로 한)이었다.

내가 할 수있는 모델을 조정 1- 0.788 x -0.578 x^2그래서 정확히 제로 신장 (보름달)와 모델이 픽셀 배율 1을 반환 할 것입니다. 4 바이트를 절약하면서도 여전히 정확도 한계 내에 있습니다.

이 모델은 모든 크기의 이미지에 사용됩니다. 달 이미지를 중앙에 배치 할 필요는 없습니다. 또한 일정 비율의 사진을 가리지 않아도됩니다.

다음은 큰 이미지와 데이터에 맞게 생성 된 포물선 모델에 대한 데이터 포인트 (신장, 표시된 MoonPixels / fullMoonPixels)입니다. 선형 모형은 적합하지만 2 차 모형이 한계 내에서 작동하지 않습니다 (아래 참조).

여기에 데이터는 큰 그림에서 나온 것입니다. 모델도

큰 초승달


아래의 데이터 (빨간색 점)는 작은 그림에서 나온 것입니다. 모델 (파란색 곡선)은 위에 표시된 것과 동일한 큰 그림으로 생성 된 것입니다.

가장 작은 초승달은 보름달 면적의 7.5 %입니다. (큰 사진 중에서 가장 작은 초승달은 보름달의 19 %입니다.) 이차 모형이 작은 사진을 기반으로 한 경우 작은 초승달을 수용 할 수 있기 때문에 아래에 적합하게됩니다. 매우 작은 초승달을 포함하여 광범위한 조건에서 견딜 수있는 강력한 모델은 더 다양한 사진으로 더 잘 만들어 질 것입니다.

적합도는 주어진 그림에 대해 모델이 하드 코딩되지 않았 음을 나타냅니다. 우리는 달의 신장이 사진의 크기와 무관하다는 것을 확신 할 수 있습니다.

작은 초승달

f이미지 i를 입력으로 가져 와서 보름달의 예상 크기를 픽셀 단위로 출력합니다. 중앙을 벗어난 촬영에 적합합니다.

아래 데이터에서 볼 수 있듯이 하나를 제외한 모든 테스트 사례입니다. 달은 전체에서 가장 줄어든 것으로 정렬되었습니다.

i_~c~t_ := Max@ComponentMeasurements[i, t][[All, 2]];
f@i_ := i~c~"Count"/(1 - 0.788 x - 0.578 x^2 /. x -> i~c~"Elongation")

사진에서 둘 이상의 이미지 구성 요소가 나타날 수 있습니다. 다른 픽셀과 분리 된 단일 픽셀조차도 별개의 구성 요소로 간주됩니다. 이러한 이유로 "모든"구성 요소를 검색하여 더 많은 수의 픽셀을 가진 구성 요소를 찾아야합니다. 작은 사진 중 하나에 둘 이상의 이미지 구성 요소가 있습니다.

큰 사진

큰 사진으로 만든 달 크기의 예측은 균일했습니다.

{"predicted size of full moon", f[#] & /@ large}
{"accuracy", %[[2]]/16416}

{ "예상 보름달 크기", {16422., 16270.9, 16420.6, 16585.5, 16126.5, 16151.6}}

{ "정확도", {1.00037, 0.991161, 1.00028, 1.01033, 0.982367, 0.983891}}


작은 사진

작은 사진으로 만든 달 크기의 예측은 최종 사진을 제외하고는 균등했습니다. 초승달이 매우 좁다는 사실에서 문제가 발생했다고 생각합니다.

{"predicted sizes of full moon", f[#] & /@ small}
{"accuracy", %[[2]]/10241}

{ "예측 보름달 크기", {10247.3, 10161., 10265.6, 10391., 10058.9, 7045.91}}
{ "정확도", {1.00061, 0.992192, 1.0024, 1.01465, 0.982221, 0.68801}}


언젠가 Mathematica를 배워야 할 것 같습니다. 골프없이 문제를 해결하는 데 얼마나 걸렸습니까?
Thomas Weller

1
@Thomas W 게시 한 그래프를 얻을 때까지 다양한 종류의 이미지 처리 기능 및 기타 (선형) 모델을 실험하는 데 2-3 시간이 걸렸습니다. 코딩은 그리 어렵지 않았습니다. 그리고 별도의 기능을 단일 기능으로 통합하는 것 외에는 거의 골프가 없습니다.
DavidC

104 :i_~c~t_:=Max[#2&@@@i~ComponentMeasurements~t];f@i_:=i~c~"Count"/(1-0.788x-0.578x^2/.x->i~c~"Elongation")
마틴 엔더

알 수없는 이유로 #2&@@@제안이 작동하지 않음
DavidC

허, 나중에 살펴 보겠습니다. 단축하는 또 다른 방법 c은 다음과 같습니다c=Max@ComponentMeasurements[##][[All,2]]&
Martin Ender

5

J, 227207 바이트 (최대 오류 1.9 %)

내 주요 아이디어는 보름달의 윤곽에있는 달의 윤곽에서 3 점을 찾을 수 있다면 이 점 의 둘레계산할 수 있다는 것 입니다. 그 주위는 보름달이 될 것입니다.

최대 거리를 가진 두 개의 흰색 점을 찾으면 보름달의 실제 대각선이거나 초승달의 끝 점이 될 수 있습니다. 주어진 시작점에서 가장 먼 지점을 선택한 다음 선택한 지점에서 가장 먼 지점을 선택하여 그래프에서 가장 큰 거리의 지점 쌍을 찾을 수 있습니다.

우리는 이전 점으로부터의 거리의 곱의 최대 값을 가진 세 번째 점을 찾습니다. 이것은 항상 윤곽과 초승달의 바깥 쪽 또는 깁스의 더 큰쪽에 있습니다.

원주의 직경은 한쪽의 길이를 반대 각도의 부비동으로 나눈 것으로 계산됩니다.

이 방법의 시간 복잡성은 입력 이미지의 크기에서 선형입니다.

암호

f=.3 :0
load'graphics/png'
i=.readpng y
p=.(,i=_1)#|:,"%.0 1|:,"0/&>/<@i."*$i
s=.%:+/|:*:(-1|.]) (([,],:m@(*&d))(m@d))(m=.p{~(i.>./)@])(d=.+/@:*:@((|:p)-])) 0{p
o.*:-:({.s)%0 o.((+/-2*{.)*:s)%2**/}.s
)

이 함수는 입력 파일 이름을 문자열로 예상합니다.

(조금 더 읽기 쉬운 버전 확인 개정 내역의 경우)

코드 설명

  • p는 흰색 픽셀 좌표의 목록입니다 (미래의 포인트라고 함).
  • 함수 d는 p의 요소와 주어진 점 사이의 거리를 계산합니다.
  • s 정의의 두 번째 부분은 3 점 목록을 작성합니다.

    • A는 목록의 첫 번째 지점에서 가장 먼 지점입니다.
    • B는 A에서 가장 먼 지점입니다.
    • C는 A로부터 B까지의 거리의 거리 값의 최대 값을 갖는 점입니다.
  • s는 삼각형 ABC의 측면 길이입니다

  • 마지막 줄은 보름달 인 ABC의 원주 면적을 계산합니다.

결과

가장 큰 오류는 1.9 %입니다.

이미지는 질문과 같은 순서로되어 있습니다.

Output  Accuracy
----------------
  16407 0.999453 NB. Large images
16375.3 0.997523
16223.9 0.988301
16241.5 0.989369
16262.6 0.990654
16322.1 0.994279
10235.3 0.999445 NB. Small images
10235.3 0.999444
10221.2 0.998067
10220.3 0.997978
  10212 0.997169
10229.6  0.99889
9960.42 0.997239 NB. Offset images
9872.22 0.988408
10161.8   1.0174
9874.95 0.988681
 9805.9 0.981768

접근 방식을 언급하고 언급 한 +1 센터가 중앙에있을 필요가 없도록 지정하지 않아서 죄송합니다. 실수로 샘플 이미지가 모두 중앙에 있습니다. 내 탓이야.
Thomas Weller

@ThomasW. 수정하기 전까지 일시적으로 답변을 삭제했습니다.
randomra

2

MATLAB (162) 156 (확실히 현재의 에러 마진)

우선 : 두 시리즈 각각에서 하나의 이미지를 제외한 모든 이미지의 정확도는 2 % 미만이며, 더 큰 경우 (약 5 % 및 14 %)입니다. 내 접근 방식은 서로 가장 먼 달의 두 픽셀을 찾은 다음 지름의 추정치로 사용했습니다.

a=imread(input(''));                 %read input image
b=a(:,:,1)>0;                        %binarize red channel
s=size(b);                           %get size of the image
[x,y]=meshgrid(1:s(1),1:s(2));       
z=(x+i*y).*b;z=z(z~=0);              %find the coordinates of all white pixels (as a list)
o=ones(size(z(:)))*z(:)';            
disp(max(max(abs(o-o.').^2))*pi/4);  %calculate the maximum of the distance between each possible pair and evaluate area formula

이것들은 정확성 결과입니다 (상대 편차 1 - (predicted size / real size))

0.0006 0.0025 0.0169 0.0500 0.0521 0.0113 0.0006 0.0006 0.0026 0.0472 0.1383 0.0131

1

C #-617

이미지 중 하나에서 기울기 (m)가 무한대가되기 때문에이 솔루션은 모든 이미지에서 작동하지 않습니다.

원칙은 이전에 언급되었습니다.

  1. 최대 거리를 가진 두 점 찾기 (빨간색)
  2. 그들 사이에 선이 있다고 상상해보십시오 (빨간색)
  3. 중간에 직사각형 각도의 선을 상상하십시오 (녹색)
  4. 녹색 선에서 흰색 점 찾기
  5. 다른 지점에서 최대 거리를 가진 것을 사용하십시오 (녹색)
  6. 세 점에서 원의 면적을 계산

설명

문제는 슬로프가 무한대 인 경우입니다. 이미지를 90 ° 또는 코드로 회전하여 y대신 축을 반복하여 문제를 해결할 수 있습니다 x.

문제가있는 달

double A(Bitmap b){var a=new List<P>();for(var y=0;y<b.Height;y++)for(var x=0;x<b.Width;x++)if(b.GetPixel(x,y).R>0)a.Add(new P{x=x,y=y});double c=0.0,d=0.0,e=0.0,f=0.0,g=0.0,n=double.MaxValue;foreach(var h in a)foreach(var i in a){var t=Math.Sqrt(Math.Pow(h.x-i.x,2)+Math.Pow(h.y-i.y,2));if(t>c){d=h.x;f=i.x;e=h.y;g=i.y;c=t;}}c=(f-d)/(e-g);for(int x=0;x<b.Width;x++){int y=(int)(c*x+((e+g)/2-c*(d+f)/2));if(y>=0&&y<b.Height&&b.GetPixel(x,y).R>0){var s=(g-e)/(f-d);var q=(y-g)/(x-f);var j=(s*q*(e-y)+q*(d+f)-s*(f+x))/(2*(q-s));var k=-(j-(d+f)/2)/s+(e+g)/2;var l=(j-d)*(j-d)+(k-e)*(k-e);if(l<n)n=l;}}return Math.PI*n;}

최소 정확도는

  • 256 픽셀 이미지의 + 1,89 %
  • 177 픽셀 이미지의 경우 -0.55 %
  • 정사각형이 아닌 이미지의 경우 -1.66 %
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.