บทความนี้อธิบายถึงรหัสตัวอย่างของ Java เพื่อให้ได้สีหลักในภาพสี แบ่งปันสำหรับการอ้างอิงของคุณดังนี้:
1: แนวคิดพื้นฐาน
สำหรับภาพสีในพื้นที่สี RGB เราต้องการได้รับสีหลักหลายสีผ่านโปรแกรมหลายครั้ง อย่างไรก็ตามสำหรับภาพทั่วไปการผสมพิกเซลสามารถทำได้ที่ทางแยกสี ดังนั้นการสแกนค่าพิกเซลโดยตรงของภาพอาจส่งผลให้ค่าสีที่แตกต่างกันมากถึงหลายร้อย ในความเป็นจริงภาพอาจมีเพียง 3 ถึง 4 สีหลัก วิธีการลบสีผสมเหล่านั้นและแยกสีหลักของ 3 ถึง 4 เหล่านี้อย่างแม่นยำตามลักษณะของภาพทั่วไปภาพจะไม่ผสมค่าสีที่แตกต่างกันที่ขอบเขตของสีเดียวกันสามารถถือได้ว่าเป็นหนึ่งในลักษณะขอบของภาพ ดังนั้นสารสกัดของพิกเซลผสมเหล่านี้สามารถทำได้ตามอัลกอริทึมการไล่ระดับสีแบบเรียบง่ายเพื่อให้ได้อาร์เรย์ค่าพิกเซลเอาท์พุทจากนั้นสแกนค่าพิกเซลแต่ละค่ามองหาพิกเซลรอบพารามิเตอร์รัศมี R ที่ระบุ หลังจากการสแกนเสร็จสิ้นอาร์เรย์พิกเซลสามารถส่งออกและจากนั้นสแกนเชิงเส้นสามารถรับอาร์เรย์เพื่อให้ได้ค่า RGB สีหลักของภาพ
สอง: ขั้นตอนการใช้งาน
1. ป้อนอาร์เรย์รูปภาพเพื่อเพิ่มภาพสี
2. สำหรับภาพสีเทาให้คำนวณการไล่ระดับสีของภาพและใช้ตัวดำเนินการ SOBOL ที่นี่
3. สำหรับแต่ละจุดพิกเซลที่ไม่ใช่ศูนย์ให้สแกนภายในช่วงของรัศมี R และค้นหาค่าพิกเซลดั้งเดิมที่ใกล้ที่สุดเป็นศูนย์
4. สแกนอาร์เรย์ที่ได้รับเพื่อให้ได้สีหลัก
พารามิเตอร์ R คือการค้นหาค่าที่เหมาะสมที่สุดตามสถานการณ์แอปพลิเคชันที่แตกต่างกัน ในทางทฤษฎียิ่งภาพมีขนาดใหญ่เท่าใดค่าของ R ก็จะยิ่งใหญ่ขึ้นมิฉะนั้นอัลกอริทึมจะไม่ถูกต้อง
สาม: เอฟเฟกต์ภาพต้นฉบับและการดำเนินงาน
ภาพต้นฉบับ
หลังจากใช้อัลกอริทึมแล้วมีการสกัดสี่สีหลักสี่สี
สี่: ซอร์สโค้ดการใช้งานอัลกอริทึม
public bufferedImage public removeBlendPixels (BufferedImage Image, int raidus) {int width = image.getWidth (); ความสูง int = image.getheight (); int [] พิกเซล = new int [ความกว้าง * ความสูง]; getRGB (ภาพ, 0, 0, ความกว้าง, ความสูง, พิกเซล); // สร้างการประมวลผลผลลัพธ์ bufferedImage resultimg = createCompatibledestimage (ภาพ, null); setrgb (resultimg, 0, 0, ความกว้าง, ความสูง, พิกเซล); // สร้างการประมวลผลผลลัพธ์ bufferedImage resultimg = createCompatibledestimage (ภาพ, null); setrgb (resultimg, 0, 0, ความกว้าง, ความสูง, พิกเซล); // สีเทาและการไล่ระดับสีไบต์ [] greydata = getgraydata (พิกเซล, ความกว้าง, ความสูง); ไบต์ [] binaryData = getGrident (greydata, ความกว้าง, ความสูง); ดัชนี int = 0; สำหรับ (int row = 1; แถว <ความสูง - 1; แถว ++) {สำหรับ (int col = 1; col <width - 1; col ++) {index = row * width+col; int pixel = (binarydata [index] & 0xff); if (Pixel> 0) {// RADIUS SCAN การดำเนินการ int mindis = integer.max_value; int minrow = -1; int mincol = -1; int nr = 0; int nc = 0; int index2 = 0; สำหรับ (int subrow = -raidus; subrow <= raidus; subrow ++) {nr = แถว+subrow; if (nr <0 || nr> = ความสูง) {ดำเนินการต่อ; } สำหรับ (int subcol = -raidus; subcol <= raidus; subcol ++) {nc = col+subcol; if (nc <0 || nc> = ความกว้าง) {ดำเนินการต่อ; } index2 = nr * width + nc; ค่า int = (binaryData [index2] & 0xff); if (value == 0) {int distance = distancecolor (image.getRgb (nc, nr), image.getRgb (col, row)); ถ้า (ระยะทาง <mindis) {mindis = ระยะทาง; minrow = nr; mincol = nc; }}}} resultimg.setrgb (col, row, image.getrgb (mincol, minrow)); }}} return resultimg; } สาธารณะคงที่ int distancecolor (int rgb, int rgb2) {// color one int r1 = (rgb >> 16) & 0xff; int g1 = (rgb >> 8) & 0xff; int b1 = rgb & 0xff; // สีสอง int r2 = (rgb2 >> 16) & 0xff; int g2 = (rgb2 >> 8) & 0xff; int b2 = rgb2 & 0xff; // ระยะทาง int rr = r1 - r2; int gg = g1 - g2; int bb = b1 - b2; int sum = (int) math.sqrt (rr * rr + gg * gg + bb * bb); ผลรวมกลับ; } ไบต์คงที่สาธารณะ [] getGrayData (int [] inpixels, ความกว้าง int, ความสูง int) {// ภาพสีเทาบิวต์ [] outpixels = ไบต์ใหม่ [ความกว้าง * ความสูง]; ดัชนี int = 0; สำหรับ (int row = 0; row <ความสูง; แถว ++) {int tr = 0, tg = 0, tb = 0; สำหรับ (int col = 0; col <width; col ++) {index = row * width+col; tr = (inpixels [ดัชนี] >> 16) & 0xff; tg = (inpixels [ดัชนี] >> 8) & 0xff; tb = inpixels [ดัชนี] & 0xff; int grey = (int) (0.299 * tr + 0.587 * tg + 0.114 * tb); Outpixels [index] = (byte) (สีเทา & 0xff); }} ส่งคืน Outpixels; } ไบต์คงที่สาธารณะ [] getGrident (byte [] inpixels, ความกว้าง int, ความสูง int) {byte [] outpixels = byte ใหม่ [ความกว้าง * ความสูง]; ดัชนี int = 0; สำหรับ (int row = 0; row <ความสูง; แถว ++) {int tr = 0; สำหรับ (int col = 0; col <width; col ++) {if (row == 0 || col == 0 || (แถว == ความสูง - 1) || (col == ความกว้าง - 1)) {index = row * width+col; Outpixels [index] = (byte) (0x00); ดำเนินการต่อ; } int xg = 0, yg = 0; สำหรับ (int sr = -1; sr <= 1; sr ++) {สำหรับ (int sc = -1; sc <= 1; sc ++) {int nrow = row+sr; int ncol = col + sc; if (nrow <0 || nrow> = ความสูง) {nrow = 0; } if (ncol <0 || ncol> = width) {ncol = 0; } index = nrow * width + ncol; tr = (inpixels [ดัชนี] & 0xff); XG + = X_SOBEL [SR + 1] [SC + 1] * TR; yg + = y_sobel [sr + 1] [sc + 1] * tr; }}} index = row * width + col; int g = (int) math.sqrt (xg * xg + yg * yg); Outpixels [index] = (byte) (clamp (g) & 0xff); }} ส่งคืน Outpixels; - ค่าคงที่ที่ต้องกำหนดไว้มีดังนี้:
public Static final int [] [] x_sobel = new int [] [] {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; public Static Final int [] [] y_sobel = new int [] [] {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; public Static Final int block_pixel_radius = 5; การได้มาซึ่งการไล่ระดับสีใช้ตัวดำเนินการ SOBOL รหัสสำหรับการสแกนวัตถุ bufferedImage หลังจากการประมวลผลเพื่อให้ได้สีหลักมีดังนี้:
ความกว้าง int = result.getWidth (); ความสูง int = result.getheight (); แผนที่ <จำนวนเต็ม, จำนวนเต็ม> colorIndexMap = ใหม่ hashmap <จำนวนเต็ม, จำนวนเต็ม> (); สำหรับ (int row = 0; แถว <ความสูง; แถว ++) {สำหรับ (int col = 0; col <width; col ++) {int pixelValue = result.getRgb (col, แถว); if (! ColorIndexMap.ContainsKey (PixelValue)) {ColorIndexMap.put (PixelValue, PixelValue); }}} // ตอนนี้สแกนค่าพิกเซล // ส่งคืนผลลัพธ์ system.out.println ("จำนวนสี =" + colorindexmap.size ()); Return ColorIndexmap.keyset (). toarray (จำนวนเต็มใหม่ [0]); รหัสทดสอบมีดังนี้:
โมฆะคงที่สาธารณะหลัก (สตริง [] args) {ไฟล์ไฟล์ = ไฟล์ใหม่ ("d: //gloomyfish//bigmonkey.png"); ไฟล์ resultFile = ไฟล์ใหม่ ("d: //gloomyfish//result.png"); ลอง {bufferedImage image = imageio.read (ไฟล์); bufferedImage result = removeBlendPixels (image, block_pixel_radius); imageio.write (ผลลัพธ์, "png", resultfile); จำนวนเต็ม [] colours = extractColors (ผลลัพธ์); System.out.println ("สีทั้งหมด:" + colours.length); } catch (ioexception e) {e.printstacktrace (); -หมายเหตุ: คีย์หลักคือการป้อนขนาดที่ถูกต้องของภาพที่จะประมวลผล ขนาดรัศมีนี้เกี่ยวข้องกับขนาดที่แท้จริงของภาพและอัลกอริทึมสามารถปรับให้เหมาะสมอีกขั้นหนึ่งในรุ่นที่ไม่ได้ขึ้นอยู่กับพารามิเตอร์รัศมีจนกว่าคุณจะพบพิกเซลเท่ากับศูนย์
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น