ตัวอย่างในบทความนี้แบ่งปันซอร์สโค้ดของการรับรู้ลายนิ้วมือ Java และการจดจำภาพสำหรับการอ้างอิงของคุณ เนื้อหาเฉพาะมีดังนี้
หมวดหมู่หลัก:
นำเข้า java.awt.image.bufferedimage; นำเข้า java.util.arraylist; นำเข้า java.util.list; คลาสสาธารณะที่คล้ายคลึงกัน { / ** * @param args * / โมฆะสาธารณะคง string filename = imageHelper.path + "// images //"; สตริง hashCode = null; สำหรับ (int i = 0; i <6; i ++) {hashCode = projectFingerPrint (filename + "ตัวอย่าง" + (i + 1) + ".jpg"); hashcodes.add (hashcode); } system.out.println ("ทรัพยากร:"); System.out.println (hashcodes); System.out.println (); String SourceHashCode = PREDECTFINGERPRINT (ชื่อไฟล์ + "source.jpg"); System.out.println ("แหล่งที่มา:"); System.out.println (SourceHashCode); System.out.println (); สำหรับ (int i = 0; i <hashcodes.size (); i ++) {int difference = hammingdistance (sourceHashCode, hashCodes.get (i)); System.out.print ("ระยะทาง hamming:"+ความแตกต่าง+""); if (difference == 0) {system.out.println ("source.jpg รูปภาพเป็นตัวอย่างเดียว"+(i+1)+". jpg"); } อื่นถ้า (ความแตกต่าง <= 5) {system.out.println ("source.jpg ภาพคล้ายกับตัวอย่าง"+(i+1)+". jpg"); } อื่นถ้า (ความแตกต่าง <= 10) {system.out.println ("source.jpg ภาพค่อนข้างคล้ายกับตัวอย่าง"+(i+1)+". jpg"); } อื่นถ้า (ความแตกต่าง> 10) {system.out.println ("source.jpg ภาพแตกต่างจากตัวอย่าง"+(i+1)+". jpg"); }}} /*** คำนวณ "ระยะทาง hamming" * หากบิตข้อมูลที่แตกต่างกันไม่เกิน 5 หมายความว่าภาพทั้งสองนั้นคล้ายกันมาก หากมีมากกว่า 10 หมายความว่านี่เป็นสองภาพที่แตกต่างกัน * @param SourceHashCode Source HashCode * @param HashCode Comparison HashCode */ Public Static Int HammingDistance (String SourceHashCode, String HashCode) {int difference = 0; int len = sourceHashCode.length (); สำหรับ (int i = 0; i <len; i ++) {ถ้า (sourceHashCode.charat (i)! = hashCode.charat (i)) {difference ++; }} ส่งคืนความแตกต่าง; }/ *** สร้างภาพลายนิ้วมือ* @param ชื่อไฟล์ชื่อไฟล์* @return รูปภาพลายนิ้วมือ*/ สตริงคงที่สาธารณะ produceFingerPrint (ชื่อไฟล์สตริง) {bufferedImage source = imageHelper.readpngimage (filename); // อ่านไฟล์ int width = 8; ความสูง int = 8; // ขั้นตอนแรกคือการลดขนาด // หดภาพเป็นขนาด 8x8 โดยมีทั้งหมด 64 พิกเซล จุดประสงค์ของขั้นตอนนี้คือการลบรายละเอียดของภาพเก็บข้อมูลพื้นฐานเฉพาะเช่นโครงสร้างแสงและความมืดและละทิ้งความแตกต่างของภาพที่เกิดจากขนาดและสัดส่วนที่แตกต่างกัน BufferedImage Thumb = imageHelper.thumb (แหล่งที่มาความกว้างความสูงความสูงเท็จ); // ขั้นตอนที่สองคือการทำให้สีง่ายขึ้น // เปลี่ยนภาพที่ลดลงเป็นระดับ 64 สีเทา กล่าวคือมีเพียง 64 สีในพิกเซลทั้งหมด int [] พิกเซล = new int [ความกว้าง * ความสูง]; สำหรับ (int i = 0; i <width; i ++) {สำหรับ (int j = 0; j <ความสูง j ++) {พิกเซล [i * ความสูง+j] = imageHelper.rgbtogray (thumb.getRgb (i, j)); }} // ขั้นตอนที่สามคือการคำนวณค่าเฉลี่ย // คำนวณค่าเฉลี่ยสีเทาของทั้ง 64 พิกเซล int avgpixel = imageHelper.Average (พิกเซล); // ขั้นตอนที่ 4 เปรียบเทียบสีเทาของพิกเซล // เปรียบเทียบสีเทาของแต่ละพิกเซลกับค่าเฉลี่ย หากมากกว่าหรือเท่ากับค่าเฉลี่ยมันจะแสดงเป็น 1; ถ้ามันน้อยกว่าค่าเฉลี่ยมันจะแสดงเป็น 0. int [] comps = new int [ความกว้าง * ความสูง]; สำหรับ (int i = 0; i <comps.length; i ++) {ถ้า (พิกเซล [i]> = avgpixel) {comps [i] = 1; } else {comps [i] = 0; }} // ขั้นตอนที่ 5 คำนวณค่าแฮช // รวมผลลัพธ์การเปรียบเทียบของขั้นตอนก่อนหน้าเข้าด้วยกันเพื่อสร้างจำนวนเต็ม 64 บิตซึ่งเป็นลายนิ้วมือของภาพนี้ ลำดับของชุดค่าผสมไม่สำคัญเพียงตรวจสอบให้แน่ใจว่ารูปภาพทั้งหมดอยู่ในลำดับเดียวกัน StringBuffer hashCode = new StringBuffer (); สำหรับ (int i = 0; i <comps.length; i + = 4) {int result = comps [i] * (int) math.pow (2, 3) + comps [i + 1] * (int) math.pow (2, 2) + comps [i + 2] * (int) math.pow (2, 1) + comps [i + 2]; hashcode.append (Binarytohex (ผลลัพธ์)); } // หลังจากได้รับลายนิ้วมือคุณสามารถเปรียบเทียบรูปภาพที่แตกต่างกันเพื่อดูจำนวนบิตที่แตกต่างกันใน 64 บิต ส่งคืน hashcode.toString (); } / ** * แปลงไบนารีเป็น hex * @param int binary * @return char hex * / private static char binarytohex (int binary) {char ch = ''; สวิตช์ (ไบนารี) {กรณี 0: ch = '0'; หยุดพัก; กรณีที่ 1: CH = '1'; หยุดพัก; กรณีที่ 2: CH = '2'; หยุดพัก; กรณีที่ 3: CH = '3'; หยุดพัก; กรณีที่ 4: CH = '4'; หยุดพัก; กรณีที่ 5: CH = '5'; หยุดพัก; กรณีที่ 6: CH = '6'; หยุดพัก; กรณีที่ 7: CH = '7'; หยุดพัก; กรณีที่ 8: CH = '8'; หยุดพัก; กรณีที่ 9: CH = '9'; หยุดพัก; กรณีที่ 10: ch = 'a'; หยุดพัก; กรณีที่ 11: CH = 'B'; หยุดพัก; กรณีที่ 12: CH = 'C'; หยุดพัก; กรณีที่ 13: CH = 'D'; หยุดพัก; กรณีที่ 14: ch = 'e'; หยุดพัก; กรณีที่ 15: CH = 'F'; หยุดพัก; ค่าเริ่มต้น: ch = ''; } return ch; - เครื่องมือ:
นำเข้า java.awt.alphacomposite; นำเข้า java.awt.color; นำเข้า java.awt.font; นำเข้า java.awt.graphics2d นำเข้า java.awt.image นำเข้า java.awt.renderinghints; java.awt.image.colormodel; นำเข้า java.awt.image.writableraster; นำเข้า java.io.file; นำเข้า java.io.fileinputstream; นำเข้า java.io.filenotfoundexception; นำเข้า Java.io.fileoutputstream; javax.imageio.imageio; นำเข้า com.sun.image.codec.jpeg.imageformatexception; นำเข้า com.sun.image.codec.jpeg.jpegcodec; นำเข้า com.sun.image.codec.jpeg.jpegimageCoder; ชั้นเรียนส่วนใหญ่สำหรับการประมวลผลภาพลายน้ำ * * @author 025079 * @version [หมายเลขเวอร์ชัน, 2011-11-28] * @See [คลาสที่เกี่ยวข้อง/วิธีการ] * @Since [รุ่นผลิตภัณฑ์/โมดูล] */คลาสสาธารณะ ImageHelper {// Project Root Directory Path String String สุดท้าย /** * สร้างรูปขนาดย่อ <br/> * บันทึก: imageio.write (bufferedimage, imgtype [jpg/png/... ], ไฟล์); * * @param แหล่งที่มา * ภาพต้นฉบับ * @param width * ความกว้างรูปทรงความกว้าง * ความสูงรูปย่อ * ความสูงรูปย่อ * @param b * มันปรับขนาดเท่ากัน * */ นิ้วโป้งแบบสแตติกแบบคงที่สาธารณะ bufferedImage target = null; double sx = (double) width / source.getWidth (); double sy = (double) ความสูง / แหล่งที่มา getheight (); if (b) {ถ้า (sx> sy) {sx = sy; WIDTH = (int) (SX * source.getWidth ()); } else {sy = sx; ความสูง = (int) (sy * source.getheight ()); }} if (type == bufferedImage.type_custom) {// handmade colormodel cm = source.getColorModel (); Writableraster Raster = CM.CreateCompatibleWritableRaster (ความกว้าง, ความสูง); บูลีน alphapremultiplied = cm.isalphapremultiplied (); Target = new BufferedImage (CM, Raster, Alphapremultiplied, Null); } target = bufferedImage ใหม่ (ความกว้าง, ความสูง, ประเภท); graphics2d g = target.createGraphics (); // ราบรื่นกว่า exlax: g.setrenderinghint (renderinghints.key_rendering, renderinghints.value_render_quality); G.DrawRenderEdImage (แหล่งที่มา, affineTransform.getScaleInstance (SX, SY)); G.Dispose (); เป้าหมายกลับ; } / ** * ภาพลายน้ำ * * @param imgpath * ภาพที่รอดำเนินการ * @param markpath * ภาพลายน้ำ * @param x * ลายน้ำอยู่ที่มุมซ้ายบนของภาพค่าพิกัด x ของ @param y * ลายน้ำอยู่ที่มุมซ้ายบนของภาพ x, int y, float alpha) {ลอง {// โหลดไฟล์อิมเมจรูปภาพที่รอดำเนินการ img = imageio.read (ไฟล์ใหม่ (imgPath)); bufferedImage image = new bufferedImage (img.getWidth (null), img.getheight (null), bufferedimage.type_int_rgb); graphics2d g = image.createGraphics (); G.DrawImage (IMG, 0, 0, NULL); // โหลดไฟล์ภาพลายน้ำรูปภาพภาพ src_biao = imageio.read (ไฟล์ใหม่ (Markpath)); G.SetComposite (alphacomposite.getInstance (alphacomposite.src_atop, alpha)); G.DrawImage (SRC_BIAO, X, Y, NULL); G.Dispose (); // บันทึกไฟล์ไฟล์ที่ประมวลผล fileOutputStream out = new FileOutputStream (IMGPATH); jpeGimageEncoder encoder = jpegCodec.createJPegenCoder (out); encoder.encode (รูปภาพ); out.close (); } catch (exception e) {e.printstacktrace (); }} /** * ข้อความลายน้ำ * * @param imgpath * ภาพที่รอดำเนินการ * @param text * ข้อความลายน้ำ * @param ฟอนต์ * ข้อมูลอักษรลายน้ำ * @param color * ลายน้ำสีฟอนต์ * @param x * ลายน้ำ */ ข้อความโมฆะคงที่สาธารณะ (สตริง imgpath, ข้อความสตริง, ตัวอักษรตัวอักษร, สีสี, int x, int y, float alpha) {ลอง {font dfont = (font == null)? ฟอนต์ใหม่ ("宋体", 20, 13): แบบอักษร; image img = imageio.read (ไฟล์ใหม่ (imgpath)); bufferedImage image = new bufferedImage (img.getWidth (null), img.getheight (null), bufferedimage.type_int_rgb); graphics2d g = image.createGraphics (); G.DrawImage (IMG, 0, 0, NULL); G.SetColor (สี); G.SetFont (DFONT); G.SetComposite (alphacomposite.getInstance (alphacomposite.src_atop, alpha)); G.DrawString (ข้อความ, x, y); G.Dispose (); fileOutputStream out = new fileOutputStream (IMGPath); jpeGimageEncoder encoder = jpegCodec.createJPegenCoder (out); encoder.encode (รูปภาพ); out.close (); } catch (exception e) {system.out.println (e); }} / *** อ่านภาพ jpeg* @param filename filename* @return bufferedImage อ็อบเจ็กต์ภาพ* / สาธารณะ bufferedImage readjpeGimage (ชื่อไฟล์สตริง) {ลอง {inputStream imageIn = ใหม่ FileInputStream (ไฟล์ใหม่ (ชื่อไฟล์)); // รับอินพุต encoder และเข้ารหัสสตรีมไฟล์ในรูปแบบ jpg jpegimagedecoder decoder = jpegcodec.createjpegdecoder (ImageIn); // รับภาพวัตถุที่เข้ารหัส bufferedImage SourceImage = decoder.decodeasBufferedImage (); คืนแหล่งข้อมูล; } catch (filenotfoundException e) {e.printStackTrace (); } catch (imageformatexception e) {e.printstacktrace (); } catch (ioexception e) {e.printstacktrace (); } return null; } / *** อ่านรูปภาพ jpeg* @param filename ชื่อไฟล์* @return bufferedImage วัตถุภาพ* / public bufferedimage readpnGimage (ชื่อไฟล์สตริง) {ลอง {ไฟล์ inputfile = ไฟล์ใหม่ (ชื่อไฟล์); bufferedImage sourceimage = imageio.read (inputfile); คืนแหล่งข้อมูล; } catch (filenotfoundException e) {e.printStackTrace (); } catch (imageformatexception e) {e.printstacktrace (); } catch (ioexception e) {e.printstacktrace (); } return null; } / *** การคำนวณค่าสีเทา* @param พิกเซลพิกเซล* @return int int ค่าสีเทา* / สาธารณะคงที่ int rgbtogray (พิกเซล int) {// int _alpha = (พิกเซล >> 24) & 0xff; int _red = (พิกเซล >> 16) & 0xff; int _green = (พิกเซล >> 8) & 0xff; int _blue = (พิกเซล) & 0xff; return (int) (0.3 * _red + 0.59 * _green + 0.11 * _blue); } / *** คำนวณค่าเฉลี่ยของอาร์เรย์* @param pixels array* @return int เฉลี่ย* / public Static int เฉลี่ย (int [] pixels) {float m = 0; สำหรับ (int i = 0; i <pixels.length; ++ i) {m += พิกเซล [i]; } m = m / pixels.length; return (int) m; -ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น