その角度は何ですか?


12

この課題の目標は、画像内の線の角度を決定することです。

画像に関する規則:

  • 画像の背景は白になります(#FFFFFF
  • 線のストロークは黒になります(#000000
  • 行はアンチエイリアスされません
  • 画像は100x100ピクセルになります
  • 線は画像の中心から始まります
  • 行は下向きになります(6-OClock)
  • 行は50ピクセルの長さになります
  • 線の角度は、開始位置から反時計回りに測定されます
  • 画像コーデックは、.jpgまたは.png

入力形式は、コマンドライン引数、スクリプト入力、または関数引数によって渡されるファイル名になります。出力形式は単純です-度数(たとえば90)を出力するだけです。

回答は、指定された測定値の±1度です。以下に画像の例をいくつか示します。

1

背景が灰色の45度の参照画像

1

0度

2

45度

3

50度

4

130度

6

230度

7

324度

画像の作成に使用されるコードは次のとおりです(これはProcessingでコーディングされています)。

int deg = 45;

int centX = width/2, centY = height/2;

background(255);
noSmooth();
line(centX,
     centY,
     centX + sin(radians(deg))*50,
     centY + cos(radians(deg))*50);

saveFrame("line-"+deg+".png");// image codec can be changed here. use '.png' or '.jpg'

1
私は下票を得ましたか?もしそうなら、投票者はなぜ説明することができますか?
Jアトキン

ファイルに保存するのではなく、表示することはできますか?
ev3commander

確かに、それは他のすべての答えがそれを行う方法です。プログラムが生成する回答をコンソールに出力するだけです。
Jアトキン

1
@JAtkin一般的に投票された投稿の投票については心配しません。c:私達は皆それを得る。
アディソンクランプ

ああなるほど。私も1つを得た私はなぜ...不思議
Jアトキン

回答:


7

Pyth- 28 26バイト

jsの回答と同じ種類のブルートフォース戦略を使用します。

f!@F+]'zm+50s*48.t.tT7d_U2

入力をファイル名としてstdinから取得します。

f                     Filters from 1 till predicate is matched
 !                    Boolean not so that only pixel with zero value matched
  @F+]                Folds by indexing to get pixel value  
   'z                 Reads image filename input
   m         _U2      Maps over both trig ratios
    +50               Adds 50 to pixel value
     *48              Multiplies pixel value by 48
      .t    d         Takes trig ratio with appropriate option
        .t 7          Degrees to radians
          T           Filter var

うわー、これはクールですが、私はピスを話しません。説明を追加してもよろしいですか?
Jアトキン

1
一方、JavaScriptのバイトカウントが同じであることを願っています。
insertusernamehere

@insertusernamehere groovyまたはscalaでこの種のゴルフができることを願っています。
Jアトキン

@JAtkinの説明が追加されました。ご質問がある場合は、チャットでお気軽にお問い合わせください。
マルティセン

9

JavaScript(ES6)、225 227 244バイト

ボールを転がしましょう:

f=s=>{(i=new Image).src=s;c=document.createElement`canvas`.getContext`2d`;c.drawImage(i,0,0,100,100);for(a=360;a--,r=a/180*(m=Math).PI;)if(!c.getImageData(50+48*m.cos(r),50+48*m.sin(r),1,1).data[1]){alert((450-a)%360);break}}

画像のURLを関数に渡すだけです:

f('90deg.png');

±1の範囲内のアラート度。すべてのテストケースに合格しました。

非ゴルフ

f=s=>{
    // create new image and set source
    (i=new Image).src=s;
    // create canvas and get context
    c=document.createElement`canvas`.getContext`2d`;
    // set width/height to 100px and draw image on canvas
    c.drawImage(i,0,0,100,100);
    // check whether for any degree on the theoretical circle a black pixel is found
    for(a=360;a--,r=a/180*(m=Math).PI;)
        if(!c.getImageData(50+48*m.cos(r),50+48*m.sin(r),1,1).data[1]){
            // wait, it should be ccw and the board is rotated 90 degrees
            alert((450-a)%360);
            break
        }
}

編集

  • 17バイトの保存 –キャンバス要素の幅と高さを設定する必要がないと考えられました。
  • 条件を否定することで2バイトを保存しました

これは動作するはずです(まだテストしていません)。206バイト:s=>{(i=new Image).src=s;with(Math)with(document.createElement`canvas`.getContext`2d`)for(drawImage(i,0,0,100,100),a=360;r=--a/180*PI;)getImageData(50+48*cos(r),50+48*sin(r),1,1).data[1]||alert((450-a)%360)}
user81655

1
あなたが幸運だからこのコードは機能します。キャンバスはほぼ毎回汚染されます。特別にfile://crossOriginプロパティを設定する必要があります。また、画像の読み込みにキャンバスの作成よりも0.00001秒かかる場合は機能しません。また、f=2バイトを切り捨てる必要はありません。しかし、それは確かに素晴らしい解決策です!!! それに対する私の賛成票。
イスマエルミゲル

@IsmaelMiguel詳細なフィードバックをありがとう。あなたはキャンバスについて正しいです。最初は、角度を変換する必要がないように、イメージを回転させてミラーリングしようとしました。それに別れを告げることができます!ぼやけてしまい、正しいピクセルが見つかりませんでした。onloadそのため、別のチャレンジでアンダーカットされたため、この部分はスキップしました。だから私はそれが十分に速くロードされると仮定するのは問題ないと思った。無名関数に関しては、どのように数えるかわかりません。切断しf=て呼び出したい場合は、次の()ようにラップする必要があり(s=>{})('arg');ます。これをバイト数で無視できますか?
insertusernamehere

@insertusernamehereええ、バイト数は無視できます。しかし、あなたは、それは無名関数であることを指定する必要があります
イスマエル・ミゲル

5

Matlab、118 104バイト

複素数(中央に0)を持つ画像と同じサイズの行列を生成し、その行列から線上にある値を抽出します。これらの平均の引数が表示されます。

@ThomasKwaに、精度の改善を提案してくれたことに感謝します。これによりコードも短くなりました!!!

I=imread(input('','s'));
[y,x]=ndgrid(-50:49);
c=y+i*x;
disp(mod(angle(mean(c(~I(:,:,1))))*180/pi+360,360))

1
線上のすべての点の平均の議論を見つけるのはもっと短いでしょうか?
リルトシアスト

うわー、これは答えが予想よりもはるかに短い、素晴らしい仕事です!
Jアトキン

@ThomasKwa絶対にですが、中心に近いピクセルは絶対に不正確なので、それほど正確ではありません。試してみたい場合は、このコードをOctaveでも実行できます。
-flawr

引数の平均ではなく、平均の引数(線の中心の引数をかなり良い精度で与える必要があります)。精度が許容範囲内かどうかはわかりません。
リトシアスト

1
@ThomasKwa素晴らしいアイデア、ありがとう!精度がさらに向上し、コードが数バイト短くなりました=)
flawr

5

Matlab、 86 77バイト

Matlabを使用する別の方法を次に示します。

[I,J]=find(~im2bw(imread(input('','s'))));mode(mod(round(atan2d(J-51,I-51)),360))

これは(flawrから盗まれた)ファイルを読み取り、黒いピクセルのインデックスを見つけます。次に、画像の中心から各黒ピクセルを指すベクトルをatan2d計算し、角度の検索、丸めによる整数角度のmod(...,360)取得、正しい範囲での結果の取得に使用します。正しい角度を取得するには(中心に近いピクセルには少し誤差があります)、最も一般的に計算された角度を使用します。

提案してくれたslvrbldに感謝しim2bwます!


1
mode(...)の前の部分を[I、J] = find(〜im2bw(imread(input( ''))));と置き換えることにより、コードを77バイトに減らすことができます
slvrbld

良いですね!おかげで、もっと簡単にできる方法があると確信しましたが、思い出せませんでした。
デビッド

3

Labview、10098バイト

別のlabviewコードをそこに置きましょう。

labviewにはバイトをカウントする公式の方法がないため、保存時にファイルのサイズを使用します。あるいは、すべてのワイヤをカウントして1として機能し、ケースを2として機能すると71になります。

1

画像を読み込み、1Dに平坦化し、両側から0をスキャンして最初の画像を取得し、ポイントに戻って計算し、ジオメトリを使用して角度を取得します。


1
いいですね、これは面白いです。labviewプログラムの採点方法をメタで尋ねることができます。
Jアトキン

スコア付けの方法についてはすでにスレッドがありますが、残念ながらまだ答えはありません
Eumel

ああなるほど。私はちょうどあなたの投稿を編集して、Aの米国でバイトカウントをより理解しやすくしました。
Jアトキン

@JAtkin欧州の仲間として、彼がどのようにしてバイトの断片を手に入れたのか疑問に思いました。スペースを使用しないでください。
アーロン

へへへ、君たちが,小数点以下の桁を持っているのを忘れた。
Jアトキン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.