Upgoat หรือ Downgoat


309

เมื่อพิจารณาถึงภาพของแพะโปรแกรมของคุณควรพยายามระบุว่าแพะนั้นกลับหัวหรือไม่

ตัวอย่าง

นี่คือตัวอย่างของสิ่งที่อินพุตอาจเป็น ไม่ใช่อินพุตจริง

การป้อนข้อมูล:

Downgoat

เอาท์พุท: Downgoat

สเป็ค

โปรแกรมของคุณควรมีขนาดสูงสุด 30,000 ไบต์

  • การป้อนข้อมูลจะมีแพะเต็ม
  • ภาพจะมีแพะอยู่เสมอ
  • ถ้าแพะกลับหัวให้เอาออกDowngoatเป็นอย่างอื่นUpgoat

การป้อนข้อมูลจะเป็นอย่างไรคุณสามารถถ่ายภาพเป็นอินพุต (ชื่อไฟล์ base64 ของภาพ ฯลฯ )

อย่าพึ่งพาชื่อรูปภาพหรือข้อมูลเมตาอื่น ๆ ที่มีคำว่า "Upgoat" หรือ "Downgoat" เนื่องจากชื่อไฟล์ส่วนสำคัญใช้สำหรับการอ้างอิงเท่านั้น


กรุณาอย่า hardcode มันน่าเบื่อฉันไม่สามารถบังคับใช้ได้อย่างสมบูรณ์ แต่ฉันสามารถถามได้ดี

กรณีทดสอบ

สรุปสาระสำคัญที่มีภาพ เริ่มต้นด้วยภาพdowngoatได้Downgoatส่งออกและเริ่มต้นด้วยภาพที่upgoatมีUpgoatเอาท์พุท

ชุดทดสอบชุดที่สอง ตรวจสอบให้แน่ใจว่าได้ทดสอบภาพของคุณในทุกกรณีทดสอบ ภาพเหล่านี้เป็นjpgs ขนาดภาพจะแตกต่างกัน แต่ไม่ว่ามาก


หมายเหตุ:อาจมีการเพิ่มกรณีทดสอบสองสามข้อก่อนยอมรับคำตอบเพื่อหลีกเลี่ยงคำตอบว่า hardcode ใดและเพื่อตรวจสอบประสิทธิภาพทั่วไปของโปรแกรม

คะแนนโบนัสสำหรับการแก้ไขภาพแทนตัวของฉัน: P

เกณฑ์การให้คะแนน

คะแนนคือเปอร์เซ็นต์ซึ่งสามารถคำนวณได้โดย: (number_correct / total) * 100


1
"เหมาะสม" นับเป็นการเข้ารหัสที่ยากหรือไม่?
Nick T

@NickT คุณหมายถึงอะไรโดย "เหมาะสม"?
Downgoat

@Downgoat กำลังหาพารามิเตอร์สำหรับแบบจำลอง (สมการ) ที่ส่งออกถ้าแพะหันหน้าไปทางที่ถูกต้อง โดย " " การปรับ " " ฉันหมายถึงการปรับรูปแบบให้เข้ากับชุดข้อมูลทั้งหมดกับชุดการฝึกอบรมบางอย่าง
Nick T


29
ฉันอยากรู้ว่าโซลูชันเหล่านี้จะจัดการกับแพะสองตัวในภาพเดียวได้อย่างไร
แดเนียล

คำตอบ:


293

Mathematica, 100%, 141 bytes

f@x_:=Count[1>0]@Table[ImageInstanceQ[x,"caprine animal",RecognitionThreshold->i/100],{i,0,50}];If[f@#>f@ImageReflect@#,"Up","Down"]<>"goat"&

นี่มันให้ความรู้สึกมากกว่าการโกง นอกจากนี้ยังช้าอย่างไม่น่าเชื่อและโง่มาก ฟังก์ชั่นfมองเห็นว่าคุณสามารถตั้งค่า threshold การรู้จำในคอมพิวเตอร์วิสัยทัศน์ของ Mathematica ได้สูงเพียงใดและยังคงรับรู้ภาพในรูปสัตว์ Caprine

จากนั้นเราจะเห็นว่าภาพหรือภาพพลิกเป็นแพะมากขึ้น ใช้งานได้กับภาพโปรไฟล์ของคุณเท่านั้นเนื่องจากการผูกไทม์จะไม่เอื้ออำนวย อาจมีหลายวิธีที่สามารถปรับปรุงให้ดีขึ้นได้รวมถึงถามว่าภาพนั้นเป็นตัวแทนของ Bovids หรือภาพรวมอื่น ๆ ของประเภทเอนทิตีสัตว์ของ Caprine

ตอบเป็นคะแนนเป็นลายลักษณ์อักษร 100% สำหรับชุดการทดสอบแรกและ 94% สำหรับชุดการทดสอบที่สองเนื่องจากอัลกอริทึมให้ผลลัพธ์ที่ไม่สามารถสรุปได้สำหรับแพะ 1 ซึ่งสามารถเพิ่มได้ถึง 100% โดยเสียเวลาในการคำนวณนานขึ้น RecognitionThresholdการทดสอบค่ามากขึ้นของ เพิ่มจาก100การ1000sufficies; ด้วยเหตุผลบางอย่าง Mathematica จึงคิดว่านั่นเป็นภาพที่ไม่สบายใจมาก! การเปลี่ยนการรับรู้จากสัตว์แคปรินเป็นสัตว์เลี้ยงลูกด้วยนม Hoofed ก็ดูเหมือนว่าจะทำงาน

Ungolfed:

goatness[image_] := Count[
                      Table[
                        ImageInstanceQ[
                          image, Entity["Concept", "CaprineAnimal::4p79r"],
                          RecognitionThreshold -> threshold
                        ],
                        {threshold, 0, 0.5, 0.01}
                      ],
                      True
                    ]

Function[{image},
  StringJoin[      
    If[goatness[image] > goatness[ImageReflect[image]],
      "Up",
      "Down"
    ],
    "goat"
  ]
]

ทางเลือกในการแก้ปัญหาโบนัส 100%

g[t_][i_] := ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]
f[i_, l_: 0, u_: 1] := Module[{m = (2 l + u)/3, r},
  r = g[m] /@ {i, ImageReflect@i};
  If[Equal @@ r,
   If[First@r, f[i, m, u], f[i, l, m]],
   If[First@r, "Up", "Down"] <> "goat"
   ]
  ]

อันนี้ใช้กลยุทธ์เดียวกันเมื่อก่อน แต่ด้วยการค้นหาแบบไบนารีเหนือขีด จำกัด มีสองฟังก์ชันที่เกี่ยวข้องที่นี่:

  • g[t]ผลตอบแทนที่ได้หรือไม่ว่าอาร์กิวเมนต์เป็นภาพ goaty tกับเกณฑ์
  • fใช้พารามิเตอร์สามตัว: รูปภาพและขอบเขตบนและล่างบนขีด จำกัด มันซ้ำ; มันทำงานได้โดยการทดสอบขีด จำกัดmระหว่างขีด จำกัดบนและล่าง (เอนเอียงไปทางด้านล่าง) หากภาพและภาพที่สะท้อนนั้นเป็นทั้งแพะหรือไม่เป็นแพะก็จะกำจัดส่วนล่างหรือส่วนบนของช่วงตามความเหมาะสมและเรียกตัวเองอีกครั้ง มิฉะนั้นถ้าภาพหนึ่งเป็นแพะและอื่น ๆ ที่ไม่ใช่แพะก็จะกลับมาUpgoatถ้าภาพแรกเป็นแพะและDowngoatอื่น ๆ (ถ้าภาพที่สองสะท้อนให้เห็นเป็นแพะ)

นิยามฟังก์ชั่นสมควรได้รับคำอธิบายเล็กน้อย ขั้นแรกให้แอปพลิเคชั่นทำงานเชื่อมโยงกัน ซึ่งหมายความว่าสิ่งที่ชอบg[x][y]ถูกตีความว่าเป็น(g[x])[y]; "ผลลัพธ์ของการg[x]ใช้กับy"

ประการที่สองการมอบหมายใน Mathematica นั้นเทียบเท่ากับการกำหนดกฎการแทนที่ นั่นคือf[x_] := x^2ไม่ได้หมายความว่า "ประกาศฟังก์ชั่นที่fมีชื่อด้วยพารามิเตอร์xที่ส่งกลับx^2;" ความหมายของมันอยู่ใกล้กับ "เมื่อใดก็ตามที่คุณเห็นสิ่งที่ชอบf[ ... ]โทรสิ่งที่อยู่ภายในxและแทนที่สิ่งที่ทั้งมีx^2."

เมื่อรวมสองสิ่งนี้เข้าด้วยกันเราจะเห็นว่าความหมายของการgบอก Mathematica เพื่อแทนที่การแสดงออกใด ๆ ของแบบฟอร์ม(g[ ... ])[ ... ]ด้วยด้านขวามือของการมอบหมาย

เมื่อ Mathematica พบการแสดงออกg[m](ในบรรทัดที่สองของf) จะเห็นว่าการแสดงออกไม่ตรงกับกฎใด ๆ ที่มันรู้และทำให้ไม่เปลี่ยนแปลง จากนั้นก็จะตรงกับMapผู้ประกอบการ/@ที่มีข้อโต้แย้งอยู่และรายการg[m] {i, ImageReflect@i}( /@เป็นสัญกรณ์มัด; แสดงออกตรงนี้เป็นเทียบเท่ากับMap[g[m], { ... }].) The ถูกแทนที่โดยใช้อาร์กิวเมนต์แรกขององค์ประกอบของการโต้แย้งที่สองของแต่ละคนเพื่อให้เราได้รับMap {(g[m])[i], (g[m])[ ... ]}ตอนนี้ Mathematica เห็นว่าแต่ละองค์ประกอบตรงกับคำจำกัดความgและทำการแทนที่

ด้วยวิธีนี้เราgต้องทำหน้าที่เหมือนฟังก์ชันที่ส่งคืนฟังก์ชันอื่น นั่นคือมันทำหน้าที่เหมือนที่เราเขียนไว้:

g[t_] := Function[{i}, ImageInstanceQ[i, "caprine animal", RecognitionThreshold -> t]]

(ยกเว้นในกรณีนี้g[t]ด้วยตัวของมันเองประเมินว่า a Functionในขณะที่ก่อนหน้านี้g[t]มันไม่ได้ถูกแปลงเลย)

เคล็ดลับสุดท้ายที่ฉันใช้เป็นรูปแบบที่เป็นตัวเลือก รูปแบบl_ : 0หมายถึง "จับคู่นิพจน์ใด ๆ และทำให้พร้อมใช้งานเป็นlหรือจับคู่กับอะไรและทำให้0ใช้ได้ในฐานะl" ดังนั้นถ้าคุณโทรf[i]ด้วยอาร์กิวเมนต์หนึ่งตัว (ภาพที่จะทดสอบ) มันก็เหมือนกับว่าคุณได้โทรf[i, 0, 1]มา

นี่คือสายรัดทดสอบที่ฉันใช้:

gist = Import["https://api.github.com/gists/3fb94bfaa7364ccdd8e2", "JSON"];
{names, urls} = Transpose[{"filename", "raw_url"} /. Last /@ ("files" /. gist)];
images = Import /@ urls;
result = f /@ images
Tally@MapThread[StringContainsQ[##, IgnoreCase -> True] &, {names, result}]
(* {{True, 18}} *)

user = "items" /.
           Import["https://api.stackexchange.com/2.2/users/40695?site=codegolf", "JSON"];
pic = Import[First["profile_image" /. user]];
name = First["display_name" /. user];
name == f@pic
(* True *)

344
Mathematica มี builtin สำหรับกำหนดแพะ ฉันไม่รู้ว่าจะรู้สึกอย่างไร
Robert Fraser

119
Whaaat Oo มี builtin สำหรับสิ่งนี้ .... ว้าว ...
Downgoat

171
คุณแพะจะล้อเล่นฉัน ...
corsiKa

27
+1 สำหรับ Mathematica สามารถดูได้ว่าภาพใดเป็น "goaty มากขึ้น"
QBrute

9
นี่เป็นเรื่องน่าขันในเชิงบวก +1
ApproachingDarknessFish

71

JavaScript, 93.9%

var solution = function(imageUrl, settings) {

  // Settings
  settings = settings || {};
  var colourDifferenceCutoff = settings.colourDifferenceCutoff || 0.1,
      startX = settings.startX || 55,
      startY = settings.startY || 53;

  // Draw the image to the canvas
  var canvas = document.createElement("canvas"),
      context = canvas.getContext("2d"),
      image = new Image();
  image.src = imageUrl;
  image.onload = function(e) {
    canvas.width = image.width;
    canvas.height = image.height;
    context.drawImage(image, 0, 0);

    // Gets the average colour of an area
    function getColour(x, y) {

      // Get the image data from the canvas
      var sizeX = image.width / 100,
          sizeY = image.height / 100,
          data = context.getImageData(
            x * sizeX | 0,
            y * sizeY | 0,
            sizeX | 0,
            sizeY | 0
          ).data;

      // Get the average of the pixel colours
      var average = [ 0, 0, 0 ],
          length = data.length / 4;
      for(var i = 0; i < length; i++) {
        average[0] += data[i * 4] / length;
        average[1] += data[i * 4 + 1] / length;
        average[2] += data[i * 4 + 2] / length;
      }
      return average;
    }

    // Gets the lightness of similar colours above or below the centre
    function getLightness(direction) {
      var centre = getColour(startX, startY),
          colours = [],
          increment = direction == "above" ? -1 : 1;
      for(var y = startY; y > 0 && y < 100; y += increment) {
        var colour = getColour(startX, y);

        // If the colour is sufficiently different
        if(
          (
            Math.abs(colour[0] - centre[0]) +
            Math.abs(colour[1] - centre[1]) +
            Math.abs(colour[2] - centre[2])
          ) / 256 / 3
          > colourDifferenceCutoff
        ) break;
        else colours.push(colour);
      }

      // Calculate the average lightness
      var lightness = 0;
      for(var i = 0; i < colours.length; i++) {
        lightness +=
          (colours[i][0] + colours[i][1] + colours[i][2])
          / 256 / 3 / colours.length;
      }

      /*
      console.log(
        "Direction:", direction,
        "Checked y = 50 to:", y,
        "Average lightness:", lightness
      );
      */
      return lightness;
    }

    // Compare the lightness above and below the starting point
    //console.log("Results for:", imageUrl);
    var above = getLightness("above"),
        below = getLightness("below"),
        result = above > below ? "Upgoat" : "Downgoat";
    console.log(result);
    return result;
  };
};
<div ondrop="event.preventDefault();r=new FileReader;r.onload=e=>{document.getElementById`G`.src=imageUrl=e.target.result;console.log=v=>document.getElementById`R`.textContent=v;solution(imageUrl);};r.readAsDataURL(event.dataTransfer.files[0]);" ondragover="event.preventDefault()" style="height:160px;border-radius:12px;border:2px dashed #999;font-family:Arial,sans-serif;padding:8px"><p style="font-style:italic;padding:0;margin:0">Drag & drop image <strong>file</strong> (not just link) to test here... (requires HTML5 browser)</p><image style="height:100px" id="G" /><pre id="R"></pre></div>

คำอธิบาย

การนำแนวคิดของ@BlackCapไปใช้อย่างง่าย ๆ ในการตรวจสอบว่าแสงมาจากที่ใด

แพะส่วนใหญ่อยู่ในใจกลางของรูปและท้องของพวกเขาจะมืดกว่าหลังเนื่องจากแสงแดด โปรแกรมเริ่มต้นที่ตรงกลางของภาพและจดบันทึกสี จากนั้นจะได้รับความสว่างเฉลี่ยของพิกเซลด้านบนและด้านล่างตรงกลางจนถึงสีที่แตกต่างจากสีที่กึ่งกลาง (เมื่อร่างของแพะสิ้นสุดลงและพื้นหลังเริ่มต้น) ไม่ว่าด้านไหนจะจางลงจะเป็นตัวกำหนดว่ามันเป็นความโกลาหลหรือความโกลาหล

ล้มเหลวสำหรับ downgoat 9 และ upgoats 7 และ 9 ในกรณีทดสอบที่สอง


4
ดี! ฉันไม่ได้คาดหวัง 100% ว่าจะง่ายมาก ฉันได้เพิ่มชุดทดสอบชุดที่สองคุณสามารถอัปเดตคำตอบของคุณได้หรือไม่?
Downgoat

นี่คือลิงค์ทางเลือกอื่นที่ใช้งานได้?
Downgoat

@Downgoat Yep อัพเดทคะแนนแล้ว
user81655

น่าเสียดายที่มันล้มเหลวหลังจากฉันหมุนภาพ 180 °แล้วพลิกในแนวตั้ง สกรีน
ช็อต

@ mr5 น่าสนใจ ... รูปภาพในหน้าจอของคุณแตกต่างจาก downgoat 4 เล็กน้อยหรือไม่ นอกจากนี้ยังมีความแตกต่างกันเล็กน้อยระหว่างเบราว์เซอร์ ด้วยพารามิเตอร์ในคำตอบนี้ฉันได้ผลลัพธ์เดียวกันทั้ง Chrome และ Firefox (โดยใช้ Windows)
user81655

63

Python, 100%, 225 ไบต์

import requests

SEARCH = "http://www.bing.com/images/searchbyimage?FORM=IRSBIQ&cbir=sbi&imgurl="
THRESHOLD = 30
url = raw_input()
print "Upgoat" if requests.get(SEARCH + url).content.count('img') > THRESHOLD else "Downgoat"

ใช้การค้นหาภาพย้อนกลับบนแพะ หากหน้าเว็บแสดงผลลัพธ์ที่น่าพอใจจำนวนนั้นอาจเป็นแพะที่ขึ้นไปด้านบน วิธีนี้อาจไม่สามารถใช้งานได้กับแพะที่วาดด้วยมือหรือหาก Bing เสียหาย


32
ฉันไม่แน่ใจว่าฉันรู้สึกอย่างไรกับคำตอบนี้ เป็นแนวเขตที่ถูกต้องและเกือบจะละเมิดช่องโหว่นี้แล้ว ขณะนี้มันกำลังทำลายกฎที่ชัดเจนว่าอินพุตเป็นไฟล์หรือพา ธ โลคัลไม่ใช่ url มันเป็นคำตอบที่น่าสนใจ แต่เมื่อพิจารณาว่าการตรวจสอบความถูกต้องตามขอบเขตนั้นเป็นอย่างไรฉันจะบอกว่าการแข่งขันนั้นน่าสงสัย
Downgoat

50
@ ลงไปเพื่อที่คุณจะได้คำตอบของเขา?
Ave

2
แก้ไขโดยการอัพโหลดไฟล์ไปที่ imgur หรืออะไรก็ได้ ^^ ทำไมคุณถึงใช้ bing ในโลก ???
Eumel

17
@Eumel เพราะ Google ตรวจสอบว่าตัวแทนผู้ใช้ในคำขอ HTTP เป็นของเว็บเบราว์เซอร์จริง (หรือบางอย่างที่พวกเขาอนุญาต) และไม่ใช่แอปพลิเคชันหรือสคริปต์อื่น Bing ไม่ตรวจสอบว่าพวกเขาหมดหวังที่จะรับคำขอเข้ามา ฉันเดา User-Agent สามารถปลอมแปลงด้วยรหัสพิเศษและจะไม่สำคัญเนื่องจากนี่ไม่ใช่ code-golf
JordiVilaplana

14
ช่องโหว่มาตรฐานนั้นมีไว้สำหรับคำตอบของการตีกอล์ฟเพื่อให้มีขนาดเล็กลง นี้ไม่ได้เป็นความท้าทายรหัสกอล์ฟดังนั้นผมจึงไม่เห็นว่าทำไมหนีจะใช้
SztupY

58

Java, 93.9% 100%

สิ่งนี้ทำงานโดยการกำหนดความคมชัดของแถวในส่วนบนและล่างของรูปภาพ ฉันคิดว่าความแตกต่างในครึ่งล่างของภาพนั้นใหญ่กว่าด้วยเหตุผล 2 ประการ:

  • 4 ขาอยู่ในส่วนด้านล่าง
  • พื้นหลังในส่วนบนจะเบลอเพราะปกติแล้วจะอยู่นอกพื้นที่โฟกัส

ฉันกำหนดความแตกต่างสำหรับแต่ละแถวโดยการคำนวณความแตกต่างของค่าพิกเซลข้างเคียงการคำนวณความแตกต่างและการหาผลรวมกำลังสองทั้งหมด

ปรับปรุง

รูปภาพบางรูปจากชุดที่สองทำให้เกิดปัญหากับอัลกอริทึมดั้งเดิม

upgoat3.jpg

ภาพนี้ใช้ความโปร่งใสซึ่งถูกละเว้นไปก่อนหน้านี้ มีความเป็นไปได้หลายอย่างในการแก้ปัญหานี้ แต่ฉันเลือกที่จะแสดงภาพทั้งหมดบนพื้นหลังสีดำ 400x400 นี่มีข้อดีดังต่อไปนี้:

  • จัดการภาพที่มีช่องอัลฟา
  • จัดการภาพที่จัดทำดัชนีและโทนสีเทา
  • ปรับปรุงประสิทธิภาพ (ไม่จำเป็นต้องประมวลผลภาพ 13MP เหล่านั้น)

downgoat8.jpg / upgoat8.jpg

ภาพเหล่านี้มีรายละเอียดที่เกินจริงในส่วนของแพะ วิธีแก้ปัญหาที่นี่คือการทำให้ภาพเบลอในแนวตั้งเท่านั้น อย่างไรก็ตามสิ่งนี้สร้างปัญหากับภาพจากชุดแรกซึ่งมีโครงสร้างแนวตั้งในพื้นหลัง วิธีการแก้ปัญหาที่นี่คือการนับความแตกต่างที่เกินขีด จำกัด บางอย่างและละเว้นค่าที่แท้จริงของความแตกต่าง

พูดสั้น ๆ อัลกอริทึมที่ปรับปรุงแล้วค้นหาพื้นที่ที่มีความแตกต่างมากมายในรูปภาพที่หลังจากการประมวลผลล่วงหน้ามีลักษณะดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class UpDownGoat {
    private static final int IMAGE_SIZE = 400;
    private static final int BLUR_SIZE = 50;

    private static BufferedImage blur(BufferedImage image) {
        BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight() - BLUR_SIZE + 1,
                BufferedImage.TYPE_INT_RGB);
        for (int b = 0; b < image.getRaster().getNumBands(); ++b) {
            for (int x = 0; x < result.getWidth(); ++x) {
                for (int y = 0; y < result.getHeight(); ++y) {
                    int sum = 0;
                    for (int y1 = 0; y1 < BLUR_SIZE; ++y1) {
                        sum += image.getRaster().getSample(x, y + y1, b);
                    }
                    result.getRaster().setSample(x, y, b, sum / BLUR_SIZE);
                }
            }
        }
        return result;
    }

    private static long calcContrast(Raster raster, int y0, int y1) {
        long result = 0;
        for (int b = 0; b < raster.getNumBands(); ++b) {
            for (int y = y0; y < y1; ++y) {
                long prev = raster.getSample(0, y, b);
                for (int x = 1; x < raster.getWidth(); ++x) {
                    long current = raster.getSample(x, y, b);
                    result += Math.abs(current - prev) > 5 ? 1 : 0;
                    prev = current;
                }
            }
        }
        return result;
    }

    private static boolean isUp(File file) throws IOException {
        BufferedImage image = new BufferedImage(IMAGE_SIZE, IMAGE_SIZE, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = image.createGraphics();
        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        graphics.drawImage(ImageIO.read(file), 0, 0, image.getWidth(), image.getHeight(), null);
        graphics.dispose();
        image = blur(image);
        int halfHeight = image.getHeight() / 2;
        return calcContrast(image.getRaster(), 0, halfHeight) < calcContrast(image.getRaster(),
                image.getHeight() - halfHeight, image.getHeight());
    }

    public static void main(String[] args) throws IOException {
        System.out.println(isUp(new File(args[0])) ? "Upgoat" : "Downgoat");
    }
}

นี่คือลิงค์ทางเลือกอื่นที่ใช้งานได้?
Downgoat

@Downgoat ใช่มันใช้ได้ผล ฉันอัปเดตคะแนน (ไม่รวมคะแนนโบนัสสำหรับอวาตาร์ของคุณซึ่งได้รับการยอมรับอย่างถูกต้อง :)
Sleafar

38

Python 3, 91.6%

แก้ไขด้วยกรณีทดสอบใหม่

ตั้งชื่อไฟล์เป็นภาพแพะที่คุณต้องการทดสอบ มันใช้เคอร์เนลเพื่อสร้างอิมเมจด้านบน / ล่างอิมเมจฉันลองโอเปอเรเตอร์ของ sobel แต่มันก็ดีกว่า

from PIL import Image, ImageFilter
import statistics
k=(2,2,2,0,0,0,-2,-2,-2)
filename='0.png'
im=Image.open(filename)
im=im.filter(ImageFilter.Kernel((3,3),k,1,128))
A=list(im.resize((10,10),1).getdata())
im.close()
a0=[]
aa=0
for y in range(0,len(A)):
    y=A[y]
    a0.append(y[0]+y[1]+y[2])
aa=statistics.mean(a0)
if aa<383.6974:
    print('Upgoat')
else:
    print('Downgoat')

3
+1 ทำได้ดีมาก! ฉันควรจะรู้วิธีการติดตั้ง PIL บน Mac จริงๆ ...
Downgoat

ฉันได้เพิ่มชุดทดสอบชุดที่สองคุณสามารถอัปเดตคำตอบของคุณได้หรือไม่?
Downgoat

@ Downgoat เพิ่งทำไป
Magenta

@Downgoatpip install Pillow
Assaf Lavie

16

OpenCV ด้วย Hough Transform, 100%

ความคิดดั้งเดิมของฉันคือการตรวจสอบเส้นแนวตั้งของขาของแพะและกำหนดตำแหน่งแนวตั้งของมันเมื่อเทียบกับร่างกายและขอบฟ้า

เมื่อปรากฎว่าในภาพทุกภาพพื้นดินจะมีเสียงดังมากทำให้เกิดการตรวจจับขอบ Canny จำนวนมากและเส้นที่ตรวจจับได้สอดคล้องกันจากการแปลง Hough กลยุทธ์ของฉันคือพิจารณาว่าเส้นแนวนอนอยู่ในครึ่งบนหรือล่างของภาพซึ่งเพียงพอที่จะแก้ปัญหาได้หรือไม่

# Most of this code is from OpenCV examples
import cv2
import numpy as np

def is_upgoat(path):
    img = cv2.imread(path)
    height, width, channels = img.shape
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 100, 200, apertureSize=3)

    lines = cv2.HoughLines(edges, 1, np.pi/180, 200, None, 0, 0, np.pi/2-0.5, np.pi/2+0.5)
    rho_small = 0

    for line in lines:
        rho, theta = line[0]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a*rho
        y0 = b*rho
        x1 = int(x0 + 5000*(-b))
        y1 = int(y0 + 5000*(a))
        x2 = int(x0 - 5000*(-b))
        y2 = int(y0 - 5000*(a))

        if rho/height < 1/2: rho_small += 1
        cv2.line(img,(x1,y1),(x2,y2),(0,0,255),1, cv2.LINE_AA)

    output_dir = "output/"
    img_name = path[:-4]
    cv2.imwrite(output_dir + img_name + "img.jpg", img)
    cv2.imwrite(output_dir + img_name + "edges.jpg", edges)

    return rho_small / len(lines) < 1/2


for i in range(1, 10):
    downgoat_path = "downgoat" + str(i) + ".jpg"
    print(downgoat_path, is_upgoat(downgoat_path))

for i in range(1, 10):
    upgoat_path = "upgoat" + str(i) + ".jpg"
    print(upgoat_path, is_upgoat(upgoat_path))

นี่คือฟังก์ชั่นทั้งหมดโดยไม่ส่งออกภาพ:

def is_upgoat(path):
    img = cv2.imread(path)
    height, width, channels = img.shape
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    edges = cv2.Canny(gray, 100, 200, apertureSize=3)

    lines = cv2.HoughLines(edges, 1, np.pi/180, 200, None, 0, 0, np.pi/2-0.5, np.pi/2+0.5)
    rho_small = 0

    for line in lines:
        rho, theta = line[0]
        if rho/height < 1/2: rho_small += 1

    return rho_small / len(lines) < 1/2

Downgoat1 edge:

Downgoat1 edge

Downgoat1 บรรทัด:

ลงบรรทัดที่ 1

Upgoat2 ขอบและเส้น:

ขอบ upgoat2 Upgoat2 lines

วิธีการนี้ใช้งานได้ดีกับภาพที่มีเสียงดัง นี่คือขอบและบรรทัด downgoat3:

downgoat3 edge สาย downgoat3


ภาคผนวก

มันกลับกลายเป็นค่ามัธยฐานเบลอและปรับเปลี่ยนแบบเกาส์เกาส์ก่อนการแปลง Hough ทำงานได้ดีกว่าการตรวจจับขอบ Canny ส่วนใหญ่เนื่องจากความพร่ามัวปานกลางอยู่ในพื้นที่ที่มีเสียงดัง อย่างไรก็ตามปัญหาของวิธีการดั้งเดิมของฉันทันทีชัดเจน: ตรวจพบเส้นพื้นหลังที่โดดเด่นรวมถึงใบหน้าของแพะในบางภาพ

def is_upgoat2(path):
    img = cv2.imread(path)
    #height, width, channels = img.shape
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.medianBlur(gray, 19)
    thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                   cv2.THRESH_BINARY_INV, 11, 2)

    lines = cv2.HoughLinesP(thresh, 1, np.pi / 180, threshold=100,
                            minLineLength=50, maxLineGap=10)

    vert_y = []
    horiz_y = []
    for line in lines:
        x1, y1, x2, y2 = line[0]
        # Vertical lines
        if x1 == x2 or abs((y2-y1)/(x2-x1)) > 3:
            vert_y.append((y1+y2)/2)
            cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 2)

        # Horizontal lines
        if x1 != x2 and abs((y2-y1)/(x2-x1)) < 1/3:
            horiz_y.append((y1+y2)/2)
            cv2.line(img, (x1, y1), (x2, y2), (0, 0, 255), 2)


    print(np.median(vert_y), np.median(horiz_y))

นี่คือ downgoat8:

ลดลง 8 นวดข้าว downgoat8 edge

รูปทรง (ไม่แสดงรหัส) ตรวจจับขอบด้านบนของแพะ (กระดูกสันหลัง) ค่อนข้างดี แต่ไม่สามารถรับรูปร่างทั้งหมดได้

รูปทรง

การวิจัยเพิ่มเติม: OpenCV มีการตรวจจับวัตถุตามคุณลักษณะ Haarซึ่งโดยปกติจะใช้สำหรับสิ่งต่าง ๆ เช่นรถยนต์และใบหน้า แต่มันอาจทำงานได้กับแพะด้วยรูปร่างที่โดดเด่น

การจดจำคุณสมบัติ 2Dดูมีแนวโน้ม (การจับคู่แม่แบบจะไม่ทำงานเนื่องจากการปรับขนาดและการหมุน) แต่ฉันขี้เกียจเกินกว่าที่จะเข้าใจว่า OpenCV สำหรับ C ++


10

Python 3, numpy, scikit, 100%

รหัสนี้ใช้ตัวแยกประเภทรูปภาพที่ผ่านการฝึกอบรมจากแพะกับชื่อไฟล์เดียวพิมพ์ 'Upgoat' หรือ 'Downgoat' โค้ดเองคือหนึ่งบรรทัดของ python3 นำหน้าด้วยสตริงขนาดมหึมาเดี่ยวและบรรทัดนำเข้า สตริงยักษ์นั้นเป็นลักษณนามของแพะที่ผ่านการฝึกอบรมซึ่งไม่ได้รวมอยู่ในรันไทม์และให้ภาพอินพุตสำหรับการจำแนกประเภท

ตัวจําแนกถูกสร้างขึ้นโดยใช้ระบบ TPOT จาก Randal Olson และทีมงานที่ University of Pennsylvania TPOT ช่วยในการพัฒนาท่อลักษณนามรูปลักษณนามโดยใช้โปรแกรมเชิงพันธุกรรม โดยทั่วไปจะใช้การเลือกแบบประดิษฐ์เพื่อเลือกพารามิเตอร์และประเภทของการจัดประเภทต่าง ๆ เพื่อให้ทำงานได้ดีที่สุดกับข้อมูลอินพุตที่คุณให้ดังนั้นคุณไม่จำเป็นต้องรู้มากเกี่ยวกับการเรียนรู้ของเครื่อง https://github.com/EpistasisLab/tpot TPOT ทำงานบน scikit-Learn, ของ INRIA และคณะ, http://scikit-learn.org/stable/

ฉันให้ TPOT ประมาณหนึ่งร้อยภาพแพะที่ฉันพบบนอินเทอร์เน็ต ฉันเลือกตัวที่ดูคล้ายกับแพะในการทดสอบนั่นคือ "ในทุ่ง" จากด้านข้างโดยไม่มีอะไรเกิดขึ้นในภาพ ผลลัพธ์ของกระบวนการ TPOT นี้เป็นวัตถุ ExtraTreesClassifier scikit เรียนรู้ ลักษณนามภาพนี้หลังจากผ่านการฝึกฝน (หรือ 'พอดี') ในแพะของฉันถูกดองลงในสตริงขนาดใหญ่ สตริงนั้นไม่เพียง แต่มีรหัสลักษณนาม แต่ "สำนักพิมพ์" ของการฝึกอบรมของภาพแพะทั้งหมดที่ได้รับการฝึกฝน

ฉันโกงเล็กน้อยระหว่างการฝึกโดยใส่รูปการทดสอบ 'แพะยืนบนบันทึก' ในภาพการฝึกอบรม แต่มันก็ยังใช้งานได้ดีกับภาพแพะทั่วไปในทุ่ง ดูเหมือนว่าจะมีการแลกเปลี่ยนกัน - ยิ่งฉันปล่อยให้ TPOT ทำงานได้นานเท่าไหร่ตัวแยกประเภทที่ดีกว่าที่มันสร้างขึ้น อย่างไรก็ตามตัวแยกประเภทที่ดีกว่าก็ดูเหมือนว่าจะ“ ใหญ่กว่า” และในที่สุดก็วิ่งขึ้นไปถึงขีด จำกัด 30,000 ไบต์ที่กำหนดโดย @Downgoat ในเกมกอล์ฟ โปรแกรมนี้จะอยู่ที่ประมาณ 27kbytes โปรดทราบว่า 'กลุ่มที่สอง' ของภาพทดสอบเสียหายเช่นเดียวกับ 'ลิงค์สำรอง' ดังนั้นฉันไม่แน่ใจว่ามันจะทำอย่างไรกับพวกเขา หากพวกเขาได้รับการซ่อมแซมฉันอาจจะเริ่มต้นใหม่รัน TPOT อีกครั้งและป้อนรูปภาพใหม่ ๆ เป็นจำนวนมากและดูว่าฉันสามารถสร้างลักษณนามใหม่ภายใต้ขนาด 30k ไบต์ได้ไหม

ขอบคุณ

นำเข้าดอง, bz2, เบส 64, อ้วน, sys, skimage.transform, skimage.io
s = '''
QlpoOTFBWSZTWbH8iTYAp4Z ///////////////////////////////////////////// 4E6fAAPR
OCLRpIfAbvhgIAAAAJCgAG68fDuYNrAwQbsADQAKBIJBITroq0UyRVNGVqljJVSvgAAAAEgAAAAA
AAO7AABugXamjQYyCIABQ6O7LEQ2hRwOdKSFCVuGgF1jBthaAUAAEgKGLVAAAAAKKCVFBIFEFKVE
DQNAaNPUGjTJjU000G1PU0ZAaaGJoyDQaDaQxPRP0oZpNo9NRGaJtRoaYmmyammnqGAjTBNpG1Ga
mT01GRoemTFNnoRNPZCm09pmP9VVVBlIgAAAmgAAExNAaBo0A1MA0ZAADRMCZoAajBNMGjTSntAC
YJgGiYJjU0YNTTCYCYTANABMATKHInox / 7VSqoZMgGQaGRoADQaDTRo00YQaAGgAGQ000yGmjQNG
mQ00DRhNADCNAAGmTIZGgaNGmgMhoZNAZDIIp4EBNACNNEMmhUjTyJ6T0h6k9qnqbTU8NCnqDaTJ
oaabTUaNqG0jIyG0T0ID1BkaGj1ABoMgGgwIxNAGhkGmTCZA0Ghk0DCKUQECYBMmIEyJhlPTU8k9
TGmpP0NNU9tRomTaU9PSep6UeIGGSGJppsU9MTKbVPyFPZMU8ET9QmmnppiJp5TT0A1PNSeJknpH
qb1T1PFGnqeqeNTSemyaT / VUEKiJAQp4JtJ6iTZNQNMgaabUBtRtTymxDUaepp6mgemp6ag9I9Ey
aaM1NGQaaDQ9TNJ6hoDag00PUaA00PUB6gNGR6jagANHqDT1DTTI9J0gKvsPxi9r9nnM1WbDVUTR
nBgijNiWaqCjE4kzhxREVREZNmqgdLCqGJUXEg0K0IUotA0AJiVHEoUpQUI0CFDQUFAlI0FUjiQc
SjQA0DRTQI0jSJRTQLSrSjUQlFBRSBSNFBQAUo0lA0CYjECNjAjiEaVChEKBKUCgxAi4gVxAA4hQ
cQABGiIMAYEDMI90oGBe6yPBxuR2XhdxeZ1XL5AOe46 / lgb3BhDEJzJA3cev7vi53o25xTVTDRTL
S1W9eT6bsd7nyJqit + oxYIxWMYiKoqLGDERRMbmDk5 / f6rkb21xwxXFwxJYkqLFNSVjGDBjFGIiE
qiASEhEiLteHuvnMwqrqQgKhgZCZiYGIVCJEec2WyYMxkzjDibGEznHXdX7PtN84txMODGGnHFxY
GsFUZxYzGSoxZjnNNLO / 3fouWnGjjcYxnGCc4xVGycVFEZjDZsNpgzOM4UxIRQSGr + hhCVYTQEJB
MhACqGoDJDAR + C + VeBCIQEqhACCRSMAEqiA0MARCEZiZkNQiKEJACuhYhx6tAQhhet2tXbimsqnn
5qIY9C5JNHDqZp2rlRGwrWGuGgdu4FIYehsHhUKrgtTZWLIJqoOGsaUi5c7iYp2n + 46rbNtk8pSy
TJoqTh822poWQW92oaGuNk4 + + Qil6VnzEKp6Lla yUQqzH9N4p / vcI1WYVfBWLk53uwVcjn / iaf1x
kZJrY15LvF3c6bDSd7rtIF / CIeJ5ySSPDS8WpbhSth1jnyu1DFRb7ulLM6NlFMEVOCorVWdxjepR
5Nc0vgBvyASUIIJt9qydSewF7mdm76qnXx7NXCsl8ZDDG2 / 7KhXbsv3S1dTtXOitVYaUPrsnj + nG
R1MPnB8p7Hvdwe4eXxf1Bf39iVuyg9r9aweH4Ht / NfXOQ4IJ + q9UqxkeHy / Br1ixpI39nqf5 / 4gm
+ + LgfXIgl7f372D VF7 / 5D + + t8jLCs H23tsPj / lnZBkV + Xn / mfuvf + 2anyF + G + bGUypcqKqpb7iCo
QlBCSaYTfNYNeoXO19viV + uYu6lckm6OXj9Tp9QzdR204Lp87r88k9ULU01rhNPleSE5XK01Nht2
wB94gHbgH5aAB / 4hTt + + y3OP41ivChK2SdsxThs4cw8p2uVsN5FTvdbYyDqkHKOdv6MDXJtk fP9U
5DFrCIhv7UQqmETgJWZWhQhDBUKlJVKRuLBari0uxZtg9q6L3K42KgbA1aXeD3ypsAhWxqK9TK59
zuFDq1sYAWeBrNuydhlVPhwDoa7rs0xZkRXtSwuyYXtqIGsoWv3eglDKBjICrev + T / pew8 // j513
S4f9JIPxCWiAoDeb + iULXivpuL37uuEfiPr764B8OuKs1SrGVPUwelyHbu0yufCuMGLcP / 3fWryq
1UsZhJYJVQkrsEZBqJpkqWQiaYqbW9MsHsp75bTgxTNiy1cdasS2yU3GLG1jf1ajXwKd + 5HugAoU
tkoFOFTCSlQpUQxsyVjWZPGsCg9gt9j818V6Kvl7v5rK1tfoqfGfF1VAAENVQVVB + TUgAKqgAArd
D3XFc7OPq9D / bjG5yjUJeo + + UtdmF4WweIIIipSUqVK2ISSVr93 lkXLVyElqLZPL12cp3sc1CkPL
5IwHHuctF9lda56rrWDJy / ueRIKFF / fVB + EAAlCWZzg3ywLIOUexFPhVz68zMJ9jK2cpO2Kkma3p
StTr71R0nR / Gqfiqg8EojIZ3LNE7UrqlPVIysrlogNqiJzimFb6yLlGnVjHz2EdpNV6XZ8iv7IdT
nN0ut93cJpaqV0cEixL2TzSPqmoXvqB6IKDm + + qmocLKnh2CWwsyqsMHtlV2 rqNzX3nVoN0Cg6vL
U2OQyZ + XMS / gMc8yPKp5AIPqjjxNohmUc6ulA8IbleVQ2twH / QC + H3QukwweIdinUphR6cPtB8oN
K8g / jbgfO3A9NhBQDKIg5IFDqBF2Yg / kQT0lA9NUPUVfVEfWEfpiJ + hQ2IB0oDtETMCZdHXCfrQN
qrthLhD0RNcJ6Y9EulXUgXS + u3LqAPVXav7EuHVO3DzA3D5IeUZxJ4DyIIPZ5HqdwIIAjH3M3O7T
zfUe5873xTd7r3pwJvknerhHzvPn6vzoOpfBAxna5nUVkZ3qsbqsQFQxLQ0IOKkjliCAI5znlbm5
ub29vY6oAAAAAAAAAAAAACqqqgAAAAAAAAAAAKqqqtGpqaM + fXWvZtXPp19ObTpWRyVSVzSaTnSZ
ISFlhCDkJ0WkkILE5KpK5pNJzpMkIm96uSToJKUXRg975M0XKsINJzoLBlWMGQ5RR0nKkFlFyRjJ
ISi6MHvfJmi5VhBpOdBYMqxgyHKKOk5QEVdE0FESD4xMmcIxOCC5hcb0F7mAXSUBk6EEkTEcoC8E
QpGkCSBCaqzovVoRckouU1WMZM95vNpRIYxVQaAgxG50kKDifCRxkiRWKxU3szGLmZHqkShKT2Fo
SIIujEYQg54EMjYyhJ5RKKM2hqbDJmxkz60YxYmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVVVVVVVVVVVVVVVVVVVVVVYygAwAAAA
AAAAAAAAADGQAFVVVYAAAAAAAAAAABVVVQAAAAAAAAAAAAAGMYxjGMYxjGAAAAAAAAAAAAKqqqxl
yZAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVVVVVVVVVVVVVVVVV
VAAAAAAAAAAAAVVVVaNXYZ9XJsNOhzoPjATZ7gjJHGZqZvMIwUCNiA3ON7mg8lirSKUQUpMTI0ZQ
NxorCSQKMFRGdFjaEZPhGEoxlKUgAAAAAAAAAAAACqqqgAAAAAAAAAAAAAMjNnzZtbNq6 + jLp12r
r2pm17IyPWUke6TzZ7lg4jfIoCcieoRCAEiwesXIqSVnqmaamnS1s + tra2wz6NGfV0Yy5cmXV058
2tp06cYYAAAAAAAAAAAAAAAAAAAAAAxjGMYxjGMYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAACqqqqq
qqqqqqqqqsZcgAMAAAAAAAAAAAAAAAAAAAAAAAAAAqqqqqqqqqqqAAAAAAAAAAAAAAxkyZcmTL5X
UABaQRUCkFAEpBFgkAQi / yAIiyQorG8kZN9kMZMAVA1v18dKaO4pB0771qIqBiQVUIgVU / 3hAHaM
ggEApEkkXUCueVjqIqwv0JBQVdUQaqXTh01SUQosK + + NiU2qmwMHABALMSQ BUXW + 7Xr09DlfqrdX
/ 939Xyc9YbJ / GjfTHd3mflYe8dzKSXup + R / HbwMZ8arVvHPdveWSm6FplrPLVmr2S843G4vE5O65
PJ4bC8DU5Luf + 6ve / Xp0 / g6un0Hj / Ty0fn2O99Haarbd32V / dny / Qc5sNf / zt7 + dwOVu9 / 5Os2eg
0vXc5p9t4dmD1nVd / lairac3oOe0vZ9V + + fSdb LsOvxsPp9V1Gn8DR6 / Y / 7 / PRP + 7La38WU / 06fv
fB8TVaynfbXa6qUu6xdNqP7 + FLY62em1Wnydnr9r3vjbDxtXkWeFrtT / nW63X6zw / E12s1 + Vsrk /
H2 + P5HkY97JyLvk5F6ud9cu5OTj3NtSvbUrsvL1VdclKMCEI / KZ + htbPr46uEYwjGMeEz24bnash
zXEx3HMzQQZAQYBB9WpqbuxABZyiDy5zuTwGgskeZ3vWc + ABzZFn1QCDPvZ0J96TVM1ENETFMVSQ
UxNFVVRK + 690eoABfv372329iVOAmoTnKmXpwCVlmZmoABwwAAAORAAzRmgM6AZ85kAc2A6TpQ0Q
AAAClc5KO1AHe90CScngj / ABrQBsQABkXAGUWSrUqVKl9 / KLRiBAYDByIgJv / fkVEE72ARUN6QQT
av4jrx7Z + + ANFQeu4oaOQ2IIM36MBCY6 yU8Yn97qjqIuOZ + 9iKAou4t0QKchQhdMMYRhCMLUcv + i
EQABvlVN9lZZYknOaiSc9 / oX6WU4KgZgAAAAAAAOS + + kDkWdAOdAAwgB98aQAAB 0dmnKykqA7gA7
w7yc1kqA8EDXNWbB4oANoeQLuMAF9XIowfMQzlqMIWrUYxtWoQjCNq1CEIxtWoQEKRQoVCgAKBEp
QKBWke4kA9PC9hAIHEkBD / IUkD2TCAb / pcCjmkJd2AO / lFXsIR35QfWwi + hkF9fKi9rCIie4gRfE
ym3CH3EHl4A9hKhxJ / BgXBwisStCQLDeYA3MB6cvZLeLKyyysFJWKUJMzOQHtgAA4gA + UAHIB9EA
M3ywBy + eAAwh0AA6MAAaU6tpQkUTAAArsropQAAA14AAMYAcbi0uNS49KlS + / Qygn9okGIUPw6YE
HpA8SfNPy / H4T7sxEA7lBBAPSIIKtIVMa6caqJDD5OfnbqJb71tVM6zwsIQAUgIwjvsAywAMqeVX
ve / 3pznOycydJCjgZyTUAAAAA + gD6gDlDlA5YDPAHOgAYTQDog6M0QBpANIB1z9llcp0nR2juO5A
AqropQAANca4P / DDADGACtWDBhnIQjyV3R / 66ny2rhCMIQh7rcOMh + Hynd5yMPK5XGdbifY0PcR3
GEI6fh9yjloxhCFqEIQhDeoQAD0YJX8q / evb4nOY3dZSk5qMzSmYnOgAADh3CgOJAA + eAcnyYAA5
gAz4wgAHSgNH1BogAFlcp9lMHagAWJaidO + AAAAAAMYACsGBCHpIWoQhpIRhDP6HjctrOQ4o6Lzb
P2RpiYdZjQD626Ff / PHsBn37P5PufLqbcUiBgCMIb3CAG6gC / VVOq9esSkUoSpIcDKyb3GZoAAAA
cYA4sA44MAAMAGdObAwQYQAH4OnAA6sdWDsHX35Uk7GgAAJ0lJRqQAAAABdumMZDbAKxRgxhnIQj
nd0ydDouH8vuGWtQhGEI6jwOK7n50c9L + 2b4 / dPObGELUIbrGEY2oxhCEN5iPNAD1QXr053vTWWJ
SoUskoK67KSAcGOCe + AA + + IAAAAPrAADmgAMIB M6I6YAAdUAdZRKnYzoDthpgFKWUkoAAAAABcu4
wAFaQwOWhCEYQjajGHm / S8dGMMH4cYwjEqlQCFz / 4edmzVADd7iqXwZpGvJyp7vSne5fDfw4NF8z
DLQjGELUIwjHeYwAADb0pelJOe7ybtQr3idApNwGYAAAAAfHAAAABmwcwcyHMgMIHPujB + UAAaUA
TlNKgAfy0wEpf1SpQAAB4oABjDGAVF9WKMCHFWoRhuXv7UIxhCEPHtRhCEYww2BF2WXkBAfUgEZs
IrLoyRRB3bAo6GrNSCDMZkPwHld4ZXqqfWZHDB1X8PQ4ftgUL2AQAJykYAAZYWWTy9 / fJSpOc92m
KTpve9Ue0nOlFAAOGAcJxYAA4180ADNgcqAc0ADnsIAB0wAdSAAT / dZOUw7XtjtwacUknKYAAANg
AAMYAOLS43x0qVKl2ZnoEoqc2QDW8f + sTtv / A1AIMUSdJOliTgaTCVQyOZxmCx6B7fdTji1wIOcL
QRhAMA0qVKupUqVOAX / V36qqqUsnPelCuzfqTy4lKlJ0ODAAAAAAAAfXA5MAwQAMJz4HQh0gAAAC
yVkqKABpgJqamlGpAADXA8YAAxjyQF9WKMCDkBWBo / f3nATMdNqPaFDUAg3zQSIg + lM20pcyohl9
R0H1pgoVnawZP7O20Wvxf2LML7Co6hNxCoxEEREIRjG1ahHfoQAUpSlKZErMmyuuVlcrLLK8zfvV
11VZV / 2d + / Vl6qqqvd5iqqqqqrhaqqqqqqqqqqqqqqqquIqqqqqqqqyePyc1k5OTkfLyMjIyMfNY
/ KY + Pj / au3bt27dzdy5cuXLlzBuXLly5z9y5cuXLmguXLly5tOh2nRbTabLF / Nh7PF6XF0eLi4uL
i4mJiYmJiYlvY4eHsuuw7du3bt27du3bt2 + 3t27du3b4HA4HA4HA4HAu9rd3d3tLu7u7u7u7v2N7
7G93u93v1 + rB5b7eYRBmhGtRBsKy / GX7nOB1 / E3 / qXrb / 3FEEsgr3NOugQYgYIUoKUpDoMnMf9JD
lIjzOcRB8V0nUZ / J2IjPhEeewNb0JbaLYXfo9aPzTK2tiN5ALOEUiEbNlrUDRlB1MS + + eEEA BDJZ
+ + PbCQi4er6zV6K2iiCwOAQHKAQEIQIgsK8HQmk 3XIg4AbHDyyj2C7CQc / V3ix6TAb7qDRb / pOt1
ebs0bSBiBYgWQEG0bTBQpV + hi7qnVA6OEHS20 / p / 23o0fEmnxQ1qhXQkQrW1g1sHjQFrLvb + iAWn
lK9nsvYQQqUWDrj30rLLFl85s4pl / CToEB2gAIQS7ZrwaSB08E27237snaWSIO7jXauo4q + b4OeE
KpUKxq14UISbjbs2RBAPUU1ezYCbpVcJlh3K9CL7 + + BIebaJl1OUvpTI aCSVpzU + Il8r4GQDpJoG
gGgR2en5fPQIPnu4x7XtkzByrR1QKTpsdMNCQYt0AaIlc2aEEAs + qCTtZfBwYICmu4fpDGr2Hjae
psCC2AKD6apD39bTAGwy + BZPQCAWOGWUaOFSbfCbMAyqoOAQQ6SDoATyAMWOZrG0hbHBBALXsyTC
ZJA53b9jyNZQ5HHH2ZGk / 13F / C + I / ZDte08YgB0kqUgG7pXT1ABAMX41Lbt4d1gi3BVNUKwAEJgH
cMJzQVfUq / x8 + DBFgv12VXO1Fpoq5i7xXVgVAAuQC4o11H6opZ07GzB1kExvmeWckaqbkCRU1iJf
Z9gDVniZ8XUg + + zZ2lCTCU5qcdLqgrZ84SqB QwNCdQVw8ADECL + / t8zQ5LrNT52orqvD4m6lPzd /
YyoxYg4ob1W / JpNtsPQ0XLzgZ0JpghiJlAIcxjlbbdBBrtkMjU5 + BG6 / xqfFgvYmQAvbmxoIE / ซีดี
BsOq6 / jpUl4ocf6meW7vnUb4YhSRX4MLMYHhJd9wgEGFLb6HBn4AED58IDj9n4vX7m2oFVibn7IE
/ RTRnVikkSXY2vf / PBBqNDu / IurbDfSqtJv8Jlu9zNdPEr / OYWQgrECDIzfa7rEYsmcgAJgIADr6
a0BBzs9qX3KO1uM9LgaY4 ++ vIxTUXMFjPWNf / n38HGXqT338kv9mub5gWYIhjiEEDd9VS / QgBAP +
UaOqjT0PBqd3W1BPQqlPNiXksoF4rxC9wqpwa6mmggb53q4Krla2yg58EZ5RfgS1wDIgOADyo6q3
fostZ4HbsAAgHi0VzeKH / GVqr7zs36oA4UJLASwUkjJSX9EH0vMrq4AQdzftzQzEGxjeY48XN7Ty
9eIT2vRrwdhb1lbJljEebtaNNsuay9FQ0NROIeNOzwh5q6ryfpvXeFFDpIApEPrRApghYIiEFM32
n1P8enSqlVMLPwez / + 7nkJ4qn04P7wd / 3UgIYz4JAQ9LZyKDz2ckVXrtJc3PJ23yu2 / PRB / VFKF /
PAnQeXIIa + + BU2EddC7OBF4kAOGhK3F5nm8SACAVVZvxO7 WQArXQrfXwkJA1bgDqrQsJlycegjze
PWc8RzzpycDyyCAe9lBwpbONqF3TcfVbssZBWPyz8cvfwXwKSAUhiQm7lasRaEEUiBQv4CRCK4r7
0 / ZmwmS5Ks77D9zvJPwJPrQK5P7QZpAF4c2zheVZwLVWQE4ke22p / W0HA3mMM + PEpCsluAVqaYux
hkHopROiQKJgKQH6Q5nUHhx7f4fynJHZ7fv + NYbllgCn / cNUv7bFd8 + qFgeAvwB ++ GA / JVNTGN53
IB4WRpQQoiVv4Q60XPHXjmIfMQdt67x / xno + j3jw8oPPoFGJxUoBg3qTG2R3KnRoEz3EJBVwrSlW
MSllN0Ngn4X88TZSSn4yioJoJgwC9nXql7l68n50Vw3ZeHSYAIB6GcHhVyOzlclfgFIXgBwAUD0Y
QE + y4AQ98kOYiVVDEicHJ7vf + f / 6Pgus8Aem43Udv3PNO76n0KYLyZ307TUBna8nIWynQx2oTMU2
dsCW8ItuBERCQQo2 + uuJ1R6nNjqxu / 4477i1foYXNYL16lbIPJgNFAcpJfRZqXv1an470C2sEQpa
qB78062iGy5rWmC7XNTOQxcOtlMlzPAzFbXONFWMAeiwgicygj / F8w / KEH / BCEBCCQe46qXWreFI
F9y41ErQyV + zGVIHdiQ8IdgeFAA0ENQYGGVvxJAfiSfaWnSggzfIveHGXibYPW7g3HaVONwuUpvX
+ TONfVrNC0QkhtuZpcGy9yii1YMQLNs9b6FS / J6TlPa2Vz8HueJYtMxYgxlY / Mxw9k5IIDkEFxsu
5pMlm13gS5cnrZoLfi4MJDy7AhQA7ANx / 1w4ckJIIn1dz86i4qNLZVG313vETqtgCatnCWfqa3 / V
aiFaoGPVKE5fBeh5cXum + + GP0Xfqs7d84PpzfD lVlIIQQECDekA + 1 + DmPqshl7IBv4LPAN9U4Hv7
kyOuussZHkeXSmLJbEG8AN4AdTJ8SHas8Lh2FO7IK8BfiEAB4gvFuCYAAMyCKwAWXxhlysSbKCqO
X5oEwpblsAcWnxmbYkhsCF0JLXTv6LC + L1sfO1IamFQALWhg0BKtHIG / pvBjlrCol / RGt72YlSDM
KgEqBPTxHR / 7gUAYIwM0ur / 11xYqAPq2AWj9vikGf8kgnEZfBftker7vGEYN54bYwDwMwPr / tvqe
78KJRD / L9R / 4vUG + + s7zBC skgZJj9JWq / MFXMd + t6sAYegSGJ / eoe4SFUEahIxBDBTE1BCJREQVU
U0UjMRUVIxMyITQjQkMTAyRFUQSoRUTVDUSECFCWoyBFIyERREIlav87qAiIuAhiVRkggn2JmQqC
mggioJIIKaihqQIgCBoq1EiKJoimJCBiaiKiImZGoCAlsO4Q4pEERVJBBCI / bsYKjMokiGDVMgMx
EqsbGCiCqZqBiZMpmSEjFX9 + Yie5UICUkMTNDEEUEGpUQkQkU0QCIiQqs6pvC42JIkSiuAMLIh7h
cZKxi5zGRmbjBlfkNThAh3PMLQJO0kJFVCY1ZjISNVMFUb45gBSU0FGZ7GfzasbgNWogMLEOxBiA
3rG1wILGbnCpq4xVjARnwHiDkCwWAfxaEYGKrctSJxcgkTHw352YiOM7UEkEEZEV5xcYEqgL4vLJ
lQfG5rWIQgJDVv4WZ0YH / UOBKMg1ICQJ0ScqApiagQi9UNwQOy2OOgHJgSAiipcTFMahJWqVEPAy
OgyCCIMwImrAQMwd8AsnblR6VGR1PQzA1mxoQ1UpndpufbhB + + JREmjK ZhXCwnQCQUzyo + ux9AvZ
UqRpnWxAQiNeRA4T0JrBB3hgs0JhpI3389AitYytiEql9bdeYIA32QwUAiJqUTuVAMSFRW5ArSph
X2wycKGIQL + 9E0FImZkAju3G9BgTj58nLbRhhLLaavCpqgl1lhwYHDMQ6IdqAJEDXb2mC1DAiQwu
QgG3tDdTjjq2TxeQQ497iMECvvmdg9JZvQQiuupKGgwcAkAiQhiRAICJkBCAliRoQXZi + 4bX6Qqf
54BVUVW3svV1AAGoDVQahr75ooWMQGImINv4HV + WYAztv1YFAagjjqoR7LekYVBEc / tyMXCATHiN
QB24EH3ogGK4HUFw1QCh9l + zAG4DhDKul9eOWUwAFzoYVdFIAuEKpeV2N0bXVBO0 / pp8g6 + hDST9
JX3d6Pdlm89PwsACoAq / D8FdDO3hpyAAAKkpodVQCtghHXJ2RErK5wbs9XElajJiizuE85V + ZXLd
Pyvy8xJOupddZ5jUTHTGEXWTNrTVo1k / u32XuDO8fpJRFzX2UKHpyclub3QmrRtnLDzSjvgEvvB7
q4UBLarBSmLSu2vTbrO + ZSbdTc6xrbEWwt8 / 5hTso2Ra / 0agqAKv3nwdsPoXaRpJHO045EGgd72y
WrVszfzjOcVKkDCwEOIem7nv2gYPreIIBQhFovlA5DCNUYscEiTK / 4V0YQc4zKxElKSGrEyJBRhK
PAJTLfnOXThkGrlpBRKpW / L4WpuVL56myXL4dfGxr + vy6pUp5lp8s1 / 1ouKjtqrb + 04ioBfm1QTY
SIn9ANIpl1WXToEahjlGBu / sZIfKlLC8pB0gZbEbvzUFDMBqCIh / tfpxRwgnx1 / 0uHx7RPieotiQ
BYWISqFAQhLiZnVVycI8REQ0Hj7lTBFPuQjs + e96w9Ab5IiX38YHg / 3D50OJjzJLSQ7bunfZDrrG
EZn35Y4fYQOEYd1c5j2D4nxPMEKJfASSWsDZqBSRwqEYNCt + 6A3vDCJarMOHPPGt513RieQyBFjJ
Fu8a7CsC / pILluBQEK4XWubGgI + Wdp5FnlHAGiMrrzB4ZyE2tsGErymPlkGDldc1J56XsL3uXUGN
4DjdYteEsK6aeWGMHQvhmLq81RyULQkPDuY7gaQmBYkohgb3TU8TrR5gannWpg + WTydjeeD3uUNA
2z63a3xxMLTHLNaIGAYkiPGHTIkiuaTyjnXCZcOvY7rJsRK / kyXWF1YxE63khaonFdmIOIZCBo1S
8dCHtB / bqoGF12thHvgxOedj4ypXY29TNWidorby8bsa3O2fAMszfcuZdsYrMudt7PnuznKXFGfC
bs9lNAERIRIXFE0ZCnSD3VOodpzSGr3hO1zz2dgHNH8x1rpXbTOd4vwiltm22MIboTvvrrnaMgO2
aUPDivhZZyHjo1YkPjedqKEBPwIL1YXRJUN4K3AIa7Q1hIQhJ8H0mrnO751mGYvCvCzd2vFl2Kdz
OdQLw7uFY8JdlkTe6SrYxCCC0N + RR6sLKYFQXlbMGu3PePLKtVuWMIndDDyJhyYbAjMxJPCltbXQ
dCxqKt047xOWRCvM3MGssh3L0aVfDoQa9SUWfXJ2 + tB1ijxCMXFzN68Awy42A7yi6e / I33xXYdoT
Cum8d6bbsI9eT8sLTdZwmoT4dvbzhMccnztjnbArbS28KEPdhw2LxfhaIiQwEdrrGa23skoq + b6x
yQCRmx8d4NB4u7B3d + + 1Ad2dt4TgUDHclmXZmD548bQgbpOTc h89SFWFt + / dEzQZAb3K6b4FHr0P
SvWlxxUdgdRuFlIZb511xtsmHbaRIXHDLYa6LDjd2dd + + XDnae3fkT RhowXYlgvFLlArArdxprHB
2ei2bilLTbbjnrpPpjG4u87QzjfHDG2PQ4c + + UoQoPQi1GAhYtCooqWg D6NHfW98ZvmkXajLdOVL
OaV6zv3Yd + + UOljp7RCtbu lqpqTkvZOe8quNevfvRQr28tcNtN3djfIsNOr9N9rZwMCI4AwwZY3r
Q91OyY6Q0jpdcnJHNGg3wySm / Lpkcl48Uvzz23RAN6SUkZt / CCivGGMsQy3pe7grdOzhlr06hTIL
77MKXMyjnhJCpHpf0w1vhmIcRDqWPZgZpHY8hztyj35vV2lIQA6cuV1fHcdfO7ud3c9m8Oeuwhll
iFMK92ZjaMsN3TVq / G + + zXvyhy3JyyyfQuVu2Y5gelrdnZ3T7Z Pbj02HeA8dy6lvQXj1319C0s0G
zbp26Wd81DXlZ5Y7dl5Wk / p0xw5deRdeuXVvBQ7bKWDTinWO ++ za9Dl1UuJXX + V6 + RKp7Bfv58pv
7szEu293TG0Lru9g0jod / fLWW1A403 + VuWVfHw0vs6FXdDJewpvINawyIumNm3b3ZO6eWG0xo1XE
cJUttx1xnV07u0516EASDuy4aEZdfJsqePd437m32UG / y7e6mW7yV7hDndG5PDC8e3m2GEOImshk
XECUiDG7xwR1pC / ciBt3gQPtrMmIQ7xRKGCJWOC3YQCrGON3BFqQEAicIEIlzgdVVQBVrmgd4xAR
AOpkqZKQphqvHn5Bu2ivV6CMZaMmkoGXCUFcRDC3sK5VM2QUZLe5VxQLXLXTu5W2B4Bj4XePi01m
5xwxtdx4U8nrloM8OnjTyV9T35WDaCCGu7jUmYhk5SZCcUDIuN17rXB + C + VqCqqoB93 / 0 + AXy4cx
I4e + Q + ถ + K30f + + 95q4G nT4Rv2MSf5wwSskQvMBCgTSN4jJ80RzxSTKq1NU5AFVpsg4AW / CmH1Re
pH1Pn + + flms88wr lKrN + 5N8RQXZfBc / TxbCjqbDwu3S2f3kk7C12cg / Cep4AOctOLvDbOWWGeMx7
LoaV2y1gWvwu63hPC6q4moW6XZ1nyryWuB7wZLgy3EDoXaaJYHOuxlwvcm6utwbo9q8DXKOG22mG
T09MXGGAxGkGt5ZzkRPtZTqhMYNi6l9j5rW / ohKV1dU3mteKvfSyL3uC8mihsFDw1jCt9bHS5ZQa
VIM05IlNE4ts2rGNhrpaYNzWnPme784eXaqimogkoiA + yxCQQwwGC / N32IVAM87DPdj + NQHqb3XH
เมกะวัตต์ + GtR3ZimnCBDwLaQX93rD5D6Pw4spVuZ9JRMjI6vQH0SE0jBgdWEHClL7KNYVAQYm0XXUBozO4
mthCt0gUb7K4vrlUpkjr / isfW5TseFDnDKusXXndg6ulr2yuvtJ5MkBrxMKWmN1uRWDgqnWs8mxM
67xWEqQmWSTuD5b / OH8o / เอฟเอฟ + 7T / 39M37r + R5ZYZ5es29pvL0vZ7ezGAxGQze04l6pvaAIfElD1j
uyCH7BJW + + ld3zg5AvvlZ4z D9K64KWyiVUyrs0xR3pejvdT1tL7vah6PmZNWILx3wpnT2J2 + w9o9
9fCuoRHQO0QLlG5 / peu1W1 + 3aXxkPXmHfam6KyERpdVrPu5pnGHOVOc3WcQgcPaNzxtyaPPLKTht
7DHvt9q0ekL9 + WEluHldE34YQEFrKwd2PY1dpTRXuZAWFY9L8MOodeuGD91x19mmWSdmA8DDQYZZ
5SVe / U4Qz7cGvBwR8Onst + nLN9d2yVrySLwjTfAE4XUSWoakBBkcOFRabcn6x4dkVtBu09nsG / สำหรับ
wdk6w5YLFCjQzPZd + qZ4boVhDVya8A7t177LqyDwxCN9cd / dHbnJ2kHEG98rUjEIxg / tEQELsG7s
tqXWlZrCZSxIFvdDZLtMjK6ImxEd4V5IVb9VfKb8uV7WcqBdXMRWI5b3cd1RMN + AaYsFEbMJQzzW
0XjyZ4ZZynCyOGN3s / a + Ol1WQ7nVrJenDHnqQW5ZGFw0AZC6unfWLmJswO21wZFFdXzE9drW2XeL
+ + 3x9rupyyfQLsDCg4vv7e7Ddm jm4Yr3Z4xjwXE3jxBxEOqB6X0HU9SRUtBRRLHUtShCEBAQgIV2
HnL8NMveS9WDDgYzXXahUuBzXMAgkaFrxPU7dAIQCKmanmTNUEd + POeU5vi9BQ8F8dwczygPKPI3
k97ou + + 81vojxP1F0z14zxt15v0sO7fY7PDVVUDAwMDAwMDAwMDAwMDAykpl56wiDx X7nyOu / W87
VVRUM1U1BcIYqqpYjnFAdIO8 ++ 9z + 18123c9z4ncBB5KCebkR / F9t93ke68F4N5YPxPrNOXzAgqK
IkgOyEIQgoQ4 + + Ecqf7fxiQMzG4Dzq Tc15Pv8WfiwVYdh2AY / Eu3ZEEQREMFlDDBEEctvdqXny + H
7vHA3fh4vt8xfP8ePyd5LynAFJ + 3Ptf8e9 + + S53hiKGmeFogi4N7lelx3fFP1fQXfeclgOhp L3qf
LPR3UIgwiDUtmDYZbbuXRBlskgmkgpuAigqeg4x79wc76P5f1Hq / bPZHv5zz9fu + 0yY8N0fTgekP
CPCnCegGfRS + NOdThqp4QiqIh5MkgA2srhW8DlKNBIAOIHLdehZ1rhPaf86uqfIIdkjao ++ JGo9T
w86Q0VNwuIOHhUB8Ry / M9Z + Aes / J1 + UjkpzxyapKT / XCGk + p38OyE46gPHBKFWigCuPMZT2NyOQo
D0g + + i0R w6YMHnJez6v2mTvUkcfAHuwFa1AQEhvRgwP0cDQZiTyfuZR0ZzJazX8HT + O + d2HEQEHl
dD8wgg + V8C8JhMUV5CznBU0kSTFERRQVZcOJiimqZrOcll0AQfTfyZ77AIPSgg752NKA73Ve41QQ
c7pv0hiRG0RBwq9jnAxxrY9SzghQwKEKGOIiDhEcojKLDJUWG9PbyPgpTThagHYQEaUAgG1dSTs +
oXMbdx8Plo4sCrEWA8F9QQO8geXGDtv7l0hCCEIQuceSfAsjITnK8GtEtmNfDVrtswvLoA3oggGy
AEAtnDgBAPbysjLWUGRMP39lpcPFNubLXsAjCseDiKeGPHtSnG1B02A3FnzXY27bkRFwFyfBj8 + R
fuwrJsqIOYmIgzgQZgIOB + LqPDsew8DsvYy3 / tWhPG1B6P59leYICPhlNfSOMAw5u1vbjyqOPIdq
Grwf9m8LwA7VLERweIe1VIJJJppJpHBWoW / uFtYQofc580Z / Baly / rcbfloWBaeQgga0RwJdh2h2
kh2hJMJ9BuuswPpY6f9sJKTg + + dtQrAXANw5QCE95VQbSHDlyhDlJCaSSSYSQhdfEO0R 71MVS0H1
fr0Iq8eT7dnneHUdxet // 3FjLpVfxuPA5vK6V66FHLYm / EAkgC9y12MngqL8pCfqfWqrN7gVMopA
Ktl7KyD + + VWq1XQkhAq6E00wkEk0ZQ4WN8 x7qsxHnhJ3HOftGUU00FkFk7wUhCp38yurSK + vlliX
KTHkDTt6gAHL4zVXzzuAZrZdF3fi7g8wAOq0IcQchff83wLVvY7OEtFGVkx / y73fCdEl8lkllliG
X5vZ / cKi932 + qA47TNANYKwHsxv1 / CrdJ4GU84VkMQH6ZRfkAiuqXpKo2B8E0LUFD + ECeVAMfd2U
lGnUr1SN96bNl2RIKsi5Vv8qKk65ZaTEWYHdMJz8GQMADTIBsOtgYFCAEF / wFR2NE1YzWGjZvIYm
JmwN3tt9sgI1 + CA93wQhG316TjKJdbFQD1QruumCcXb / 1T89JcWGYUqGC1vWFPOY2VNL + VnGUaxe
qU1ZldElC24hK / Zlr / kn68N99aonkCAc5kIDFRg / u3y5Ca0lAKQEBg0EjitScs3s9UWFaODgGFoQ
SoAYAUyD60EK6hyVeJV2nXubIAQC2rcrXMJgO7Wrzp2jpMkUEn21JIUvACkOwhpC + Cj37Cr7ndLb
VyHWC2rebx97BJWkOSHJFzQTpnLpSN1uL3qpGRkJvFEgA6 / 0UlFtKy9MbwFF9Dch6Cgh4PkCgEJH
nb / 8mNdfaF3vfr7au3g2e9QY / ZvaEXsTXoqrr6Ki8AKcZQefTZ7cbZoAF30kOXAyCmFuIwF4UdLz
0wdAG + BTCHux7Zn0gDjB2MdwuKkEwkFDm7BQVG9SwqBBobKAEIC2 / qAkLTiVLH2CGVhR6w7 / zz2G
4qJvs / 4A8vRolTkZVBMIEHk / 0DY7B9m1HviOXEWHb1g0gDX9c4k1IQgnCpZb7goDH + EsATHHfW5r
LbGMAWAUPpdrgI6VRESgUKyE5IhMCUSAXF0OPutXyU / nldne719lra1OAJrDNoAcxAbsbiGwnR87
b212K + + 23VUvGA31TynD GeTAQd57WVlBBwfMfH2G9vVKnFU8bad5XlBJJEkiFq7dOqXbc5 + hUgkk
Yaa9Fz1zAwu94 + Q99j5oAB5qtyAfmp7WcjfbM6KL1gjHoSxkv5u99UuF6vpKFrj1olNXufcCSOvh
fd2xlKG / 7XF43ZAvvtmmwMSQEIN5zZVXBSEhR0z6p1kwQQIlMXAxuO6 + + Sz0KSzlMz5WwmOP 5Kui
qyT4ndILsW9CQYQcAodKQlQArUr + ssfHwtTCpILqqo / RgAn + lIAD9mt / zGlUfQ + + JjFIiPvA ZQBp
NWASGpwEHoHCMCERNb2spMiGGdf5lPB2LP76yDuSA / RcQA3CtAvgCE0AXFBfnEx / JLzDNpVN + Oeh
RDKQomGH8ZM0NuzZmn79Hfc4YPup93UHasgv4QggaJHOn1EwiDfAQG9PJ / HYVl1QopWPXywz / U9S
rhfVhWVmAAfiHRe7oEgno + nUBx0EdXoiDg64EG / DBBsgg9aCDM6Oqmz0QfL8dEG6FBrs0iDwuvBB
7bTyRdep5XiYJve8Jn9x2GM6qbeJfw0cfXRFa2WDuk8 / cby9fjROB5FpqFykYm1PLvHxr9qmCrlQ
3MSgOa1zfHbyfH4DKpqUvbDard1K03Worpp08ulIiD8kBJ + xixlpbofFrr5GvR995mAmIg7LlEQa
3spgCDg7 + CD + JEG9DhQQdgIPiwQfIQIPnbrfHZznOc5znOc5znOcg5ByDkHIOQcg5ByDkHIOQcg5
ByDkHIOQcg5ByDkHIOQcg5ByDKpKpKpKpKpogBBm6P8NdyPJefd6HrvsfT2 / rcLO5bK + Fd / 6 + LKK
KpzXN8vf85ofW7rtf77ynFU + + GBH cLn4VHj6WRcDVAg1NyoDLWqA / xzf0dnh9zw9DlqpVTZe1pvE
mKqfhKA + + ถู LOQedMIYxhoxjAYgxJdnGCsYxiMlmDFioJrGMFNUUZYxeY8t57CYorx1nOCppIkm
KIiigqy4cTFFNUzWc5LLuin9UAB + + PfrIJy6Pr eJnNDmJ6W2MzCjO6nVR5IAKGIFqf5QCt0NykAp
yABANmbqCWA9SHG3q / fyKs8ArifkXP + + VZ0r6UUrSp1SWcynqM3JfGGb TCzdL5gKXUGufguANt9v
Ggo1uIp7qnq8YPU1TcaHnc60 / WXABx + o3NBl6vpnESB7Qe3arD7KR7GaKE0 / 6fCWKsuwc + gHKXeR
4VsFtjLcunY8sAnADS2SRNmAretAvcMkVr2Schn81VtvUD / snTAHjMfR7ALTtdjoLsSwiQDcVyUB
AkPgLWrSIdgKC8A5oVqH / dhxxcHj2dYznw2OcwKpyAXkyo8wkxm6GWybIiwjlYlJ8WGtsjSTLmfQ
YoltFrJy4WhtlrPd0fJ + + 5RV7zyAmXXmQBz0Eb4IGo4j HFyuxC5hmA + Lp7XGM6VBwKRtqmGZKoL8
Q + g1DSBrpMd / IFP + + MvHBZ JBE6kC6ANXFK2cfW8wgD0q5KxwFQVFWgB / mQaMAd56DKEBg3yHHvMD
hOJemYWGWffGSSokFQhNBj6gfMGpzy9QO7zQ5a8CFA98Mv0CgfzfuHIKdPp6gAPD8ABDIPxPP997
00/1 + + 7Vf0M oxq9jy5ThAnvnJmTj + + 2OYOg5CZyJE8f 3uXucXvDP9T + + SDeO ISnbL4bpVUABUYVL
7gXNX / LoTNp / Ym9nFudlNVYiRURymZRUkQUSLMrFBnwVWIkVPTq / 8u5U7jm / + IbMP2rfw3WSe55f
07XWWsziJFRHqfxqHNvwzZRVf3qVwc5C51vnWzfqnmasiQUz + G / fJRxMwp65aQcziraVQVB51ABt
gNsB7zG2DaA2gNsBtoG1BtQehOlzvA22DsB7TaByDxgdwHdyDsB1BgdQZoNUDbjTAzwZwM8GQG8A
zwaIN4Bmg6g7AcA4B0B1B0B0B2gdQcg5BwDug6g4B0B0BgdA25O0tgO3vA7gNEGgDRBkBogzwZ4N
MDNBmg + zPBlByDqDsB0B0B2wdNQdAdAcA7oPY7QOQfqNgOwGB2G9IbAd8HdB2wdgO0DgGeDOBxBT
g1IMp86u6Alr2mBsKcGoBlBpzpeXoGzgiImdM8ryUktMDWAzweZw + DqgayrvFO1YNiDUA7QPJ0Bg
yDv8AM8aHdnQHV2gddbaBtNAdm1zITAPADug7oOwHcBwDtA7AeODwA6g6g7AcA4B0B1B0B0B2gdQ
cg5BwDuA6g4B0B0BgdAdAdwHYDmyeDOBngyA0wM8GiDTA + / OBnAzwZAcA6g7AdAdAdwHUHIOQcA7
wOoOAdAdAYHQHQHeB2A7AdQdgOAd0HYD6HcB3gdgOwHaBwDgHQHYDoDoDtg6g5ByDgHdB1BwDoDo
DA6A6A8xTqUKCmvoqUFKKkilQpRUnqU6k1SapOUkUkUmKTVNpNUmqUVJyl / mKT5qminEU21MKaqd
tqphT + HYG / FV2rh21OMpUKUylBSipIpOUnKU6F9B / UDkrP6SW8gOEGEPQ6gHrR4h7AexQYQd3VOQ
Q5kCey9eYBCoBYBqCcoNtZ7 + lYPlQ5EZ0fwSB / St4j013Mj796pDwCEQBm0CAgEgpnKuxT6CMeKs
kFMsHy8JQdwgqxELgrIaSywjHJLQubX1C7AyKXGirdk5H946pfTw / XYoSR63vmvLksL76P1OwACB
hBDWusoCggvyACoQSAQYV7Cw4CBAImcuMkZG4aSZTgFkAAn5LcC + + a1Wyqo9CCRnc RC3 + qLLLcNC
uZhQbgEGoxHOdhRL8F8 / liQxLf5kmp4qe / 33a2Ifbq / iyvacKwD3hAA7GIHX6MvCCKFUwFNBw1zw
cTvqiTlOP9KfzgEArnQBgcS4FPROW2ZdJoXbJGrzV5UeSjVBoAUD6v679RAg7XKhiQOmHHRc / VE2
HDegnENsOjHiz4yDYdb3eNY + IESh7XQgJDIrVA86uvicQoRfF0tFcwWrKLp7OoFr1ihsAblmMh4p
uIrW8exXq82p07OUnfw07QdCJDy2FaHZNmQRhcreIP2XUqHdfXen8krrwwQP9yOMxwVANQC / z1vJ
IEQQGcJdetX5q2ftJ2wM9Kj + rngQmC3PhSSAEmj874BadAqcp0TGT0FW1eKpIrD1rh6p / IJJG101
lx8bL5xf6gL89IEAI4IBCSWG3OiOaUqTo3bqCg7zKA73qrQ7zbC8hH + 97gcnxYaafW7KAkLqugCA
AOkUapcHf2jLhgHHedVmxgdas8utk5eurnq4DLQm5q9Zq9R4uy5ME3AwoQJ + 6RGRCECRkJYCAgIZ
WWAkJaBBhQamA5 / H9TiredrDtvtaCZhRb2knhxvtzJ8wLQHVS5nbSXjlMCAwURQ84JAOtPEFc5vL
tA3y2anUm4 + + KCWSD6Ao8fRFuTr9 d7V1SYFXxsFzbPofblVbcAo21b3u / UfU2qy6y6f54Hk0IOq6
L + 722ZguAaRAOw7vtUyqOshz1I8bzS2O29n0Xe2YHPQYcXgIPAQAGt7kG8x7K5JoQiaRM7VI0tLv
IzZtYzZutjNm1jMDkGByGtFc9ZAdQYHUGB2bNSpoyA6gwOoMDl0JIwA6AwOgMDnQoiKwA6AwOgMD
nSCrY5AdQYHUGB1dZijADoDA6AwOmjVMYVNFIUmKQpLMidOlIlZgpOU + + XtLcv Ro9X10bv9O23QX
7SXom0IIf3783F4pv39Hd5mApYbSLiSSEgXwO2Bh / X9Klcmc4s7ur8hIODmidLHN8l2Dzm17p770
นาโนเมตร / v / ZeD8VVVfAxiMRiMRiMRiMSOAYBwDAOAYBwDAOAYBwDAOAYBwDAOAYBwDAOAYBwDAOAYBwDC
mFIUwpEiHp5hzUO9MUV + evADDkP70VrEkDS4YAtctpD1 / JLDtsPG0gb / UlKiuB6Lor3bc4AayABK
2H6AIMv5AEGw2nTf19GskBAMPpNPm79DmTgiArc9l7a8F5Pn0kKRAg6tAEEgJwcU0AofWwmlBCog
aSYorSvhH0eTViKn + + EVEcUjVghr6SMacICSGQegFn errwXxHkzS2eAFY + kDmfhyVYaAHfOIWsON
2vIUbiBJz4GGp7J7ZmrAl + 8znekOADQSzQMmnd2djdZ2M42gxyWkpoS0Z / vz6iraIOyH / wgFImr9
HwOFslabdTMuJGdceuFXIz3k / HiqW5CEEzz + / + 68Cx84flyhY57tPmrL3W6XTk HBMuD4dNfyseDx
IEUgAJiBFRbZ6Ya4GTBJCu3aIgUNlzPNZMwD7e3doqIb0FU5NKLU36M1UcrY9Zasd000667DsA9O
2fezKtc0ACZ96QKVVd38AfCG + lH95C0jZTjIjz6LPCndEesoM8EAfJwBU3FtBf8LbLAs7jxvq8Tv
qoHj1Pae3itldbEtbHIcaQtA / T2gM7Xy / l2IIPrHIq0YFyTSFAEghN6EW32UGufZb2p5n770BUPd
gGLMAfmgBuHBIQ6QPrac9eHQrlo346lJmu412dxLYjEIJa27hVHQ5WBrsGxeZ6EW1JTf / Ds66sUn
LNwD3st9HUGCOrbltE3rSsVdTqt / 46l9lVHB9IcEhNC5jmbvWBY8 + + rEt2c Jz1c0fcK2A9FcYwTA
A33hM4C9W90n4jy9xX2gHpQRxa1Z1rQoRoUACz3TvKeTcgKk2UWvmRgkhruhdfJB1LFUmlBvONB +
ogvCBXwgvXE9OtwY00kuCfLAeAC2cHo3Sc7Wnhg3AN3 + + ejuKl274 XOx8kGQLf5 / PZW4YNShBAzn
ZvPOAUxyGtz0Xw7uwfqxzoni0IADC8UZcAGqKHfASyl0YOKxbQqmJ6qXPBKbgCBkbvJZe38D4TnS
EnhPRyyWUAAZhmLoo0RIFrpIKAeTvE4ZGApO7IHx8pmW4B0cIyysrDK9RK7ldiJ2xH + ZDOqZwrV5
IWgGf7BHacj / zjs8ZbVBy9AUjrtH9JP5V7NZBeS4AMLFxmnU / 8Pc5vhAGd2F5ye7J4uNqoBwjEtg
DyjMXm4fg1m / FN2ThVG0YUeHwfbViOzBSZFVGnmIt6cOggOX3cQ / XPHXWqW8EBV1hQYuqCtAef2q
5lDUA / HV + a4U ++ br2PUbhM0H3qP0gPAmWccEEjwi1 / j3N8RrT61o7DlIYADnWrl2vfanPXD + wVxc
AHX9CiUM7sTo7RMmFosktmAOVS900leEdROCR9iM7Zs50p6PyHffleg / IdqBEVdI78gAIEBcqbA6
FAMB + eJr253U7kbWK / Do + z3uLlW3WIGwx / + / + 6px9fuOCCh AL6daPfFXSr5Wvz2rr / c2cTW1uwRt
Gc7N2jfXIEC6LC8JHoQxn8UlslTC12NnCT7 / p84AcFqB74ViQ2B / NAOGsjL7wADq1Y1idU0gXzgJ
z88WoQzkNP8l1JN28Y0ueW4fW + + 9OnI4BN1nsGYrVnP0EK0Du4DLYPxZ6 H5IAbEsqbE / AAaflq3m
9v0nPc5TZKryWWwAqe0CQEPCBjwEFLClfLzMRDf7YJDSfdpIGNKxkMtxQz5mVUuH8nmz7sA7IKm3
q3zz6tTuHKxCLJjIbhWPoQw7RfzxvrXlyRV0ErIXEc3z5Nu142U1ZEhrdds99MbUNgDHyT3MIDTc
WTHq8NW7x1yYLqK2g5n2gCWIAVQkoB9Sd9R8ml0EHnCQpfuAgkVF7p + hcu2sGhA7UHFb / K54c7kH
JT2rtbgiECCaa7y7a3AtQ8x / YnegM1rOa3AEgILxcTuc8NXIGxKAcmgcqncSKFm0 + GVh34Ks4Ca6
mLKrDRkAdJE7fvjlTdyZd6IZeFjoMBUr0Oss8GZIEA8JAX15gXYBSulrshIayPQtWZJwK94rAkiA
Nvf3mmAvGj + + 2mK I1rAkorUZmznVe7sM7WTagTq8TvPdsJyJVh2sWSQmeunSj + i4dOY2YDXzsRBY
H6cxvacIkQXGZKDpUABP8UcNslpUMFyWYINks4Ais3c7LfRktkuLU0SAM + + ghrSZPZanGAPMBE สวัสดี
QzPqo1s6rtlvFSGZlBGUAXB2B60DBoBjeP / vQgJa5eDI + 1T62TF / 7V0mY39eHq8fr17sAovGM3EV
p22sGHrTr8poMFo9rlh / ekPpVtgDqcIkmx4AD647TveT4tgtIJd2RoIIYliGIUPWwPloB9vIeqgf
cw8 / AHwYBCsMtKPj4Q3YA1nsoFDkynvLIdBCq + 3j8iPGQAUCPgQqQBEVeYvbBQQdaLoAUiXpA06D
iU1wwBubeq + awjNNYAf656ARWVRVg2yabvpLxuu8n / 0m6PRdwus5QSfuMQDn9jvw8JQthjErS5AO
4 + + lodu6lZ9t1fwXjTfZTx855NErDYAuLtSqJlQ2sWDiuttyP8zoxnrf4xtV XLA / dKJXjYjA0q2t
41b0lD9 + Qk0 / iefL3GlEkAqkJFBsxOdndROfSLc5CczexkbfYo / qReS1WrbuyAHQB / Cr72MFRKrK
eZ21Cj22nfpw27rIBTJaAHU8e3azXR3SvGMvWvcZcAgHNdyu2shZN4zZOf3h6 / rlEPSuSEw + IEog
pci7XfcxtvD2oORT / k / YLQ / Cq7nu1pvh4xIZNAdgG0H0ubtGvpfo8bOEPr72fBeuzS4G7jMAcwWF
27ALsMvbKdiYk758z1fhZ2tpE582oakBCDQpYLb2f9aaIVde2s07g / YmQ7K / 4hMXjjv / vydgAAHQ
so9Qndo / gHfAMfN4bq559ZJvb9uXqspwG9t85m88P5 + Rr4aOSdOAgVlikVHyd2Ti3HmKBi / MqaDV
sL1wnAE / ugR4gKqO / JC8W22Jze5spAZvgZQABAHIQmjKk5GtKIji7fxd1TQdaKuPNiFUFWJS65ED
L8z9yBQjcAwxBBYEEAsH4A2Pyua7maKaRlLL19G3fKeTethH7eWqznAFAdIQSJG4csaHOYnnS / OX
OOHLz8lZFKrC0uU3JBd6GNU6sAhYHhEwgm3AHBDEV3azVaxnDsmWxXKeZ66gYHfVOQvAAfnmKdAA
BIEPC8QQIyeprt8vV1H5c5vaVWRPLOCM3l6atqSeFYOWBegAvIdAGgntK2Uj5vwFD4VlJKRlVC0J
z7nP3MFqAVT7rRek8F / ZY / 7AZCE1Mrg2UBFgb3MwWGPk5njynv4mSpr8zgQJVAA5f2WelIGtynR4
eJZ7SHrvi9vVrAGyAhaHV1CaAlNhwXdaqGcgCRBIub9r50A4P453oWfa3 / f1novK3rrL0cO4g3SK
af + J5ll / sWAnU9Qg + 7GsMugb1ndCCCgnUIOCxgAps78HV6c2X8Pd5fpr99Tvf99P7ZH36B82eSfM
zPMVDxYTi4TULbd9 + HWsQBk0FnkMj7sKQBqbHS8W2fZvLjn9dn2ne1C8G8udbkfmv4OO1Hv / zKzf
W / 4AYYDnjbtA5BuaCPj + + 2deggY 4fpvWkp / 7SWnnYjYdHgsPzmsdvs2BQGr3 / iVIjIZqXj5dxXoc
QxEggGx2rMV7F88Te7m62r2tH5M7Oqu1 / VivenvOV7fciH0WjqZr5PVHvRXfy / olOD8Vzpv8KmJJ
GVj2z9btv797opNtz / ++ ljzO6sve + + 7v7PIf3X zwH / 490QCcPwaLh2wUq6aAI15GitK8xY / VBAmD
Y4wECM2NzkWYHL1PCtuLlm + KZ0fN2uW2X8QbS7RlG / 1hWL7ZKPCigVz + ow7W1exUYkkdhiNj1rhS
6aPGP03 + + 8vp81Tydlr9vBVV3dtdNQeC9a7swGT7LHEKLnz6TbcjF6 sEDIrebWc6 + + symQJF8 0DA
KIQE9316H0UJ3jfRil5W0zvf / m96XYOGW5m + RA8DZsIaS1NVa8 / qbc03xlIbFgaf8czo6TwZy4Qq
6oXJBwkckTuv3j + TEAfx2s2lorR9max28vusi + X + + UFAWnWPsdzOw5p6pTVKjx FrlFxff + 0 / W8Z2
PFX + lo5 / jvwnM3Ej6fonL / tG9Jb5lthrAMgMbgqyDfUELd7f73lQZ + + kBSgP 5d58WT9mRlNjT2vN
/ K96yv + + uCy2PxPsoZa1Qdn4X deSU7Mn1VyW9ymSQKfkeYaeSFbQQKvLHS8ezgjOE31LchHRplOT
7nwrrfv / VQ6Cevfo + 9LEdvZfx0PjiVPWsMq3S0cR9sC5ulgk4 / NXKv4aNFQ8 + z6Wja74nE4aVJGN
hax + pB0f8 / CranGLVF51Dbk9HG / bYcCo2Yk9bMrOGN6uh7hZNvCgkCJAEdUbMrNL3sh / YGOpv5I5
RL6cXmOAqaCWoDU7jrXfDDSWkkHmkoPI2H0TFz3N + ooK6ez89y49HZqWWzn / prn7z29WzUMpP87P
dR1vh97fLrzLn8QJe + FggQcJyeQOqBBoH5zrPAnmGE3UVGwbVa6 / ข้าวโอ๊ต / wImAcgKDCXq4 / vZJLZ8C
O / 7L3zaNrYvjeRX7FlrJVvRe46TEw9oJm92C15gE5MLfFg4MgSJIqsL85CjaswBXvKP6gf8DQjpb
7bohufI7 / Lfve / V68Rt59Vw6Ccwklrdt3fWv4U9Ieqm + 6TBAt4H6i12qZuCaoPl01QZoD7VYqZSO
qqsZxhuB14YOQ2TqJDxrIupeT4ezp / e96svnMfH4HSdX3WTqPRTyrIkgdE / xfn3mdk3FEiamcZz +
aN4bEDzY8kLcViBKY0ADNEfO0FMDk3s + + lVIqehPUL9zsT 7fOu / szXSwUQiJiwSF6XxxN + zGIqIh
b / 2eZF1JSQHRInCCL8Kx0wCBSFH4kIOVRkINIwSrZp9MLEur90Z / LHG + FIfX25SLhuiTEUsxgSBC
W8u7Vyoa5oyOt47 / 9LW1jCRvAt9QHWIFoA4hPiHxKjYD4RKsZYYCEix / 7v4jmv / BoJ + w73wg17ei
UfWmS9Gym1Mvk6DIVAAA2dVFlODLKZ7CKFV2XZd8JfU3aSJdOX / 7CXC82dxOaGh4 / t2OkzHr1feY
3uchvA0E3hbXh / e9xL5f1NrmhDcAdYFaN3xjnWcGtPmboVrR + 425TFUK90qF50vGqFIQ8vB23tgr
hk + + BmYDp8XppnmIAFVtly8H9CdxfBVdKDAfpCHsxgOg8r s7TmgnFB4khuezp8eGRNAbDeBYM3k +
S0tX6iPW1vuU6PkPBhiN6ZbuWqEi5r8EgQxRdSMDrm2C2wJ35ItBOIAwgNYAwhzwCnjFYaYLe4zo
hUtVOw + SabSJGRo5RqKoG1ur7sug33u7uA6fT6D2EgmX863NQOqpYgC7iC1XuSDmQ8ejtoHUz7Xj
+ wAwK2VU4shsdl8KjrAD3Ec / x4iIhh6cfC / Ux8CaDwWCCEZNWAhBRwF2aHZQhCA / mrFo + VN / Qvbg
cEblqZlCXbDMb60IqgnNJUAjFwAQhCHd9gYGJYuGvqlApR6hSmG4n1IQIfSXftZLPZhCwOdMJARs
b2u4hFb2ggZGvjM / hJSUNI / 3 / f6ycRymgi4X / ลำลูกกา / HWKpUDqAw / เจ / jx7eXc76q1P2DLJI8S / a / nV6
S5Ud56prWfrixl + + o6wtGlyvkOqos1oPAECxSyM5KaMCjlLFIDx ej59Fkdf8jAjUZvw / yBT6ygvL
oeLO214jL3sfoifigCAfaz2OsowBeZ + + RF2 6nkyfF09j90 + + bpttxO3Hx14I5ct4Q9jH93j nVR2g
hEAxAMQqkMKV / kWXwzc77t52KJz2q1zmq1S4G1x69Kz + OA / QU4AB / 2y1xh6PhsZtoWaHyDu0S5IQ
aSh8LeP31 + wIGbyOZVPkM2n / YjAUNv2bEHXhYHIFvQT9yf8RCXZd4vl6ASrnKLI + d2qYnNrUW1Ng
NlAj0rf5VkhJxFSCanG + + iIcyyqL4qX9xHgAA mluM1rrwAtLkkd1ofd87lZem + qk1KEb5dpDbi7q
hgDK2LduIJ5owSR57uIuyP6wkaW2JAprdq9w9EpFoUeSbl7a7F9PjWsiBmAgY3r3ePVBlVEoMPe3
O9cQdd6PWGEBoO37at + + 5DF QAGt09ODv53V / e5D1ECNjYVlx / s + + fB3 yrXxFKOWJJzXMe / Qtqhjg
IljLH0OeH6nbW3U5Tf78Q0uY6rxzGXG + + F8C0K4a E4nmxVxbwit7QEFOk2lfszEG + ggIIlbcPP6G
S / 84Fp8AMwakQn2JjdgACpWYA7bjIRrLGtDkL0EC / wzdu + + ttg9GUvl3BuQv7OJHS9NQBw YEEKV0
BXkDbI36AKvsHLP1g1 / iP8aSBr8podjCY2fuLHnOOX4sthQSSyUwlC97ntxmDg28dRtbzRuQ0wP8
3V62hO9nc7X9fb9fznzhRBNYF5IFEEjJQBIKIJmK7I8Xh5Pn9xywJX7HKInI9jqQQbwACgmCD1RR
BPBFEE // F3JFOFCQsfyJNg ==
'''
พิมพ์ ([ '', 'Up', 'ลง'] [int (pickle.loads (bz2.decompress (base64.b64decode (s))). คาดการณ์ (numpy.array ([skimage.transform.resize (skimage.io .imread (sys.argv [1], as_grey = True), (24,12), โหมด = 'คงที่'). แผ่ ()])) [0])] + 'แพะ')

อัปเดต: คำขอต่อไปนี้เป็นข้อมูลการฝึกอบรมปรับขนาดเป็น 24x12 และรวมเป็นภาพเดียวเพื่อให้ง่ายต่อการอัพโหลด / นำเสนอ มันเกินหนึ่งร้อยภาพ http://deeplearning.net/datasets/ , http://www.vision.caltech.edu/Image_Datasets/Caltech256/ , ค้นหาภาพ duckduckgo, ค้นหารูปภาพของ Google, ฯลฯ

ข้อมูลการฝึกอบรมที่ 24x12 พิกเซล


คุณสามารถโพสต์ข้อมูลการฝึกอบรมของคุณได้หรือไม่?
qwr

ภาพต้นฉบับที่แน่นอนที่ฉันใช้มีลิขสิทธิ์ดังนั้นฉันจึงไม่สามารถโพสต์ได้ทุกภาพอย่างไรก็ตามฉันมีการย่อขนาดรูปภาพที่ใช้ในระบบ 24x12 และโพสต์ในภาพตัดต่อเดียวซึ่งควรมีคุณสมบัติเป็น ' การใช้งานโดยชอบธรรม '
อย่าสดใส

6

Scikit เรียนรู้กับป่าสุ่ม 100%

วิธีการพยายามและความจริงคือ convnets แต่ป่าสุ่มสามารถดำเนินการได้เป็นอย่างดีออกจากกล่อง (พารามิเตอร์ไม่กี่ที่จะปรับแต่ง) ที่นี่ฉันแสดงเทคนิคทั่วไปบางอย่างในงานการจำแนกภาพ

ฉันเริ่มต้นด้วยแพะ 100 ภาพเพื่อการฝึกอบรมที่ฉันพบผ่าน Google Images (AFAIK ไม่มีใครในข้อมูลการฝึกอบรมที่ตรงกับข้อมูลการทดสอบ) แต่ละภาพจะถูกลดขนาดเป็น 20x16 ในระดับสีเทาจากนั้นอาร์เรย์จะถูกทำให้แบนเพื่อสร้างหนึ่งแถวในอาร์เรย์ 2D รูปภาพที่พลิกแล้วจะถูกเพิ่มเป็นแถวสำหรับข้อมูลการฝึกอบรม ผมไม่จำเป็นต้องใช้เทคนิคการเสริมข้อมูล

ตารางแพะ

จากนั้นฉันป้อนอาเรย์ 2 มิติลงในตัวแยกประเภทฟอเรสต์แบบสุ่มและเรียกการทำนายเพื่อสร้างต้นไม้ตัดสินใจ 50 ต้น นี่คือรหัส (ยุ่ง):

RESIZE_WIDTH = 20
RESIZE_HEIGHT = 16

def preprocess_img(path):
    img = cv2.imread(path, 0)  # Grayscale
    resized_img = cv2.resize(img, (RESIZE_WIDTH, RESIZE_HEIGHT))
    return resized_img


def train_random_forest(downgoat_paths, upgoat_paths, data_paths):
    assert len(data_paths) == 100
    # Create blank image grid
    img_grid = np.zeros((10*RESIZE_HEIGHT, 10*RESIZE_WIDTH), np.uint8)

    # Training data
    TRAINING_EXAMPLES = 2*len(data_paths)
    train_X = np.zeros((TRAINING_EXAMPLES, RESIZE_WIDTH*RESIZE_HEIGHT), np.uint8)
    train_y = np.zeros(TRAINING_EXAMPLES, np.uint8)

    TEST_EXAMPLES = len(downgoat_paths) + len(upgoat_paths)
    test_X = np.zeros((TEST_EXAMPLES, RESIZE_WIDTH*RESIZE_HEIGHT), np.uint8)
    test_y = np.zeros(TEST_EXAMPLES, np.uint8)


    for i, data_path in enumerate(data_paths):
        img = preprocess_img(data_path)

        # Paste to grid
        ph = (i//10) * RESIZE_HEIGHT
        pw = (i%10) * RESIZE_WIDTH
        img_grid[ph:ph+RESIZE_HEIGHT, pw:pw+RESIZE_WIDTH] = img
        flipped_img = np.flip(img, 0)

        # Add to train array
        train_X[2*i,], train_y[2*i] = img.flatten(), 1
        train_X[2*i+1,], train_y[2*i+1] = flipped_img.flatten(), 0

    cv2.imwrite("grid.jpg", img_grid)

    clf = RandomForestClassifier(n_estimators=50, verbose=1)
    clf.fit(train_X, train_y)
    joblib.dump(clf, 'clf.pkl')

    for i, img_path in enumerate(downgoat_paths + upgoat_paths):
        test_X[i,] = preprocess_img(img_path).flatten()
        test_y[i] = (i >= len(downgoat_paths))


    predict_y = clf.predict(test_X)
    print(predict_y)
    print(test_y)
    print(accuracy_score(predict_y, test_y))

    # Draw tree 0
    tree.export_graphviz(clf.estimators_[0], out_file="tree.dot", filled=True)
    os.system('dot -Tpng tree.dot -o tree.png')


def main():
    downgoat_paths = ["downgoat" + str(i) + ".jpg" for i in range(1, 10)]
    upgoat_paths = ["upgoat" + str(i) + ".jpg" for i in range(1, 10)]
    data_paths = ["data/" + file for file in os.listdir("data")]

    train_random_forest(downgoat_paths, upgoat_paths, data_paths)

นี่คือแผนผังการตัดสินใจแรก (แม้ว่าจะมีโมเดลอยู่ในชุด แต่ก็ไม่มีประโยชน์อย่างยิ่ง )

ต้นไม้การตัดสินใจ # 0


นั่นเป็นเรื่องที่น่าสนใจมาก .... ข้อมูลการฝึกอบรมของคุณดูเหมือนจะเป็นรูปภาพที่หลากหลายมากกว่าของฉัน
ดอนสดใส

@donbright ฉันจะโพสต์ข้อมูลการฝึกอบรมของฉัน แต่โฟลเดอร์ที่มีรูปภาพทั้งหมดของฉันอยู่ในฮาร์ดไดรฟ์ที่เสียชีวิต หากใครมีความทะเยอทะยานเพียงพอพวกเขาสามารถใช้การค้นหารูปภาพของ Google แบบย้อนกลับและค้นหารูปภาพที่ฉันใช้
qwr

ก็เท่ห์ ฉันดาวน์โหลดรูปภาพจำนวนมาก แต่ฉันใช้เวลานานมากในการจัดเรียงรูปภาพเหล่านั้นเป็นภาพ "สะอาด" เป็นที่น่าสนใจที่จะเห็นว่ามันเป็นไปได้อย่างไรในการฝึกฝนโดยใช้ภาพที่“ สกปรก” มากขึ้นโดยไม่ต้องใช้เวลาในการเรียงลำดับมากนัก
ดอนสดใส

@donbright ฉันเชื่อว่าข้อมูลการฝึกอบรมและความหลากหลายดีกว่า สำหรับ "สะอาด" และ "สกปรก" เราอาจใช้การเพิ่มข้อมูลเพื่อสร้าง "ข้อมูลเพิ่มเติม"
qwr
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.