อัลกอริทึมที่ดีที่สุดสำหรับการทำสำเนารูปภาพเอกสารในตัวอย่างนี้คืออะไร?


31

ฉันกำลังพยายามใช้อัลกอริทึม binarization ต่าง ๆ กับรูปภาพที่แสดง: ป้อนคำอธิบายรูปภาพที่นี่

นี่คือรหัส:

clc;
clear;
x=imread('n2.jpg');     %load original image

ตอนนี้เราปรับขนาดภาพเพื่อให้การคำนวณกลายเป็นเรื่องง่ายขึ้นในภายหลังสำหรับเรา

size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');

z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);

ตอนนี้เราพบว่าค่าเฉลี่ยและส่วนเบี่ยงเบนมาตรฐานที่จำเป็นสำหรับอัลกอริทึม niblack และ% sauvola

m = mean(v(:))
s=std(v(:))
k=-.4;
value=m+ k*s;
temp=v;

% การนำ niblack thresholding อัลกอริทึม:

for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
k=kittlerMet(g);
figure;
imshow(k);
title('result by kittlerMet');

การใช้อัลกอริทึม thresholding sauvola:

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

ปลาย

figure;
imshow(t2);
title('result by sauvola');

ผลลัพธ์ที่ฉันได้รับมีดังนี้: ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

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


1
คุณสามารถใช้ข้อมูลสีเพื่อทิ้งพื้นหลังแทนความสว่างเท่านั้นได้หรือไม่?
endolith

เคารพคุณ / ม่าย ฉันกำลังทำโครงการเกี่ยวกับการประมวลผลภาพฉันเป็นแนวคิดที่น่าสนใจ binarization .. โปรดตรวจสอบและแก้ไขการเข้ารหัส ... ฉันใช้รหัสและเรียกใช้โปรแกรม แต่ข้อผิดพลาดบางอย่างเกิดขึ้นการเข้ารหัสนี้ ... ฟังก์ชั่นที่ไม่ได้กำหนดหรือตัวแปร 'g' และอีกอันหนึ่งคือข้อผิดพลาดใน msp (บรรทัดที่ 31) k = kittlerMet (g); .. วิธีการแก้ปัญหา ... โปรดแก้ไขการเข้ารหัส ...
muthu

คำตอบ:


49

รูปภาพของคุณมีความสว่างไม่เท่ากันดังนั้นคุณไม่ควรใช้เกรตสม่ำเสมอ คุณต้องมีเกณฑ์การปรับตัว สิ่งนี้สามารถนำมาใช้ได้โดยการประมวลผลภาพล่วงหน้าเพื่อให้ความสว่างสม่ำเสมอทั่วทั้งภาพ (โค้ดที่เขียนใน Mathematica คุณจะต้องใช้เวอร์ชัน Matlab ด้วยตัวคุณเอง):

วิธีง่ายๆในการทำให้ความสว่างสม่ำเสมอคือการลบข้อความจริงออกจากภาพโดยใช้ฟิลเตอร์ปิด:

white = Closing[src, DiskMatrix[5]]

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

ควรเลือกขนาดตัวกรองที่ใหญ่กว่าความกว้างของฟอนต์แบบอักษรและเล็กกว่าขนาดของคราบที่คุณพยายามลบ

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

  • ลบโครงสร้างที่มืดขนาดเล็กกว่าองค์ประกอบโครงสร้าง
  • การหดตัวของโครงสร้างที่มืดขนาดใหญ่โดยขนาดขององค์ประกอบโครงสร้าง
  • การขยายโครงสร้างที่สดใส

การกัดเซาะจะทำตรงกันข้าม (จะเลือกพิกเซลที่มืดที่สุดภายใต้องค์ประกอบโครงสร้าง) ดังนั้นหากคุณใช้มันกับภาพที่ขยาย

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

ดังนั้นการดำเนินการปิดจะลบวัตถุสีดำขนาดเล็กที่มีการเปลี่ยนแปลงเพียงเล็กน้อยกับวัตถุสีดำขนาดใหญ่และวัตถุสว่าง

นี่คือตัวอย่างที่มีขนาดองค์ประกอบโครงสร้างที่แตกต่างกัน:

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

เมื่อขนาดขององค์ประกอบโครงสร้างเพิ่มขึ้นจะมีการลบอักขระมากขึ้นเรื่อย ๆ ที่รัศมี = 5 อักขระทั้งหมดจะถูกลบ หากรัศมีเพิ่มมากขึ้นคราบสกปรกขนาดเล็กก็จะถูกกำจัดออกไปเช่นกัน:

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

ตอนนี้คุณเพียงแค่แบ่งภาพต้นฉบับด้วย "ภาพขาว" นี้เพื่อให้ได้ภาพที่มีความสว่างสม่ำเสมอ (เกือบ):

whiteAdjusted = Image[ImageData[src]/ImageData[white]*0.85]

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

ตอนนี้ภาพนี้สามารถถูกนำไปต่อยอดกับเกณฑ์คงที่:

Binarize[whiteAdjusted , 0.6]

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


5
ว้าว! นี่มันเจ๋งจริงๆ! +1 มาก!
Phonon

@nikie +1 ดีมาก - คุณหมายถึงอะไรโดยการปิดตัวกรองจะต้อง "เลือกให้ใหญ่กว่าแบบอักษร" ความกว้างหรือความยาวของตัวอักษรใด ๆ นอกจากนี้ตัวกรองปิด 'ทำอะไรจริงๆ? ขอบคุณ!
Spacey

1
@ Mohammad: ฉันได้เพิ่มคำอธิบายเล็กน้อยเพื่อคำตอบของฉัน และใช่สิ่งเหล่านี้เป็นการดำเนินการที่ไม่ใช่เชิงเส้น หัวเรื่องทั่วไปคือการประมวลผลภาพทางสัณฐานวิทยา
Niki Estner

1
@ นิกกี้ไม่เป็นไรสีขาวคือสูงสุดไม่ใช่สีดำ :-)
Spacey

1
@ gdelfino: ฉันมักจะพยายามหลีกเลี่ยงโดยใช้หน้ากากที่มีขนาดใหญ่พอและใช้ในClip[ImageData[white],{eps,Infinity}]กรณีที่ eps มีจำนวนน้อยเพื่อความปลอดภัย
Niki Estner

6

คำตอบของ Nikie นั้นดีที่สุดและดูเหมือนว่าจะสามารถทำงานและให้ผลลัพธ์ ดังนั้นจึงเป็นผู้ชนะที่ชัดเจน

อย่างไรก็ตามเอกสารประกอบที่ฉันเพิ่มการอ้างอิงอีกหนึ่งที่อาจเร็วมาก

เทคนิคนี้มีชื่อว่า Adaptive thresholding ซึ่งไม่ต้องการเรียนรู้พื้นหลังอย่างชัดเจน

โดยพื้นฐานแล้วแทนที่จะค้นหาขีด จำกัด โกลบอลที่เหมาะสมที่สุด- เราสามารถแบ่งรูปภาพในหน้าต่างโลคัล (พูดประมาณ 7x7 หรือเหมาะสม) และค้นหาขีด จำกัด ที่เปลี่ยนไปตามการสำรวจหน้าต่าง

การอ้างอิงด้านล่างมีรายละเอียดวิธีการที่แน่นอน http://homepages.inf.ed.ac.uk/rbf/HIPR2/adpthrsh.htm

วิธีนี้จะค่อนข้างเร็วกว่าการคำนวณ


สองสิ่งนั้นไม่เหมือนกันหรือ การประมาณค่าเฉลี่ยของสัญญาณท้องถิ่นก่อนที่จะทำการเพิ่มค่าใหม่หรือไม่
Maurits

1
@Maurits ดูเหมือนว่าความแตกต่างหลักคือการสั่งซื้อและสถิติที่ใช้ ตัวอย่างเช่นในโอเปอเรเตอร์เปิด / ปิด (ซึ่งประกอบด้วยการขยายและการพังทลาย แต่ตามลำดับที่แตกต่างกัน) หน้าต่างจะถูกสแกนแรสเตอร์และจะมีการใช้สูงสุด (เหนือสิ่งอื่นใด). อย่างไรก็ตามในเกณฑ์การปรับตัวค่าเฉลี่ย / มัธยฐานสามารถนำมาใช้แทนค่าสูงสุด
Spacey

OP ถามในSOด้วยซึ่งฉันตอบ แต่โดยหลักการแล้วฉันไม่คิดว่าจะมีความแตกต่างใด ๆ ระหว่างคำตอบหนึ่งมักจะประมาณสถิติท้องถิ่น หากคุณปรับเปลี่ยนการกำหนดเกณฑ์ขั้นต่ำคุณจะได้เรียนรู้พื้นหลังในกระบวนการ
Maurits

6

อีกวิธีหนึ่งโดยใช้ตัวกรอง bandpass (ใน MATLAB) การเล่นกับความแตกต่างของพารามิเตอร์ Gaussian อาจให้ผลลัพธ์ที่ดีกว่า โดยทั่วไปกระบวนการนี้จะทำการกรองภาพเพื่อลบภาพพื้นหลังที่มีความถี่ต่ำซึ่งจะทำให้ปกติเป็น [0,1] ซึ่งจำเป็นสำหรับคำสั่ง 'graythresh' และภาพเกณฑ์

โหลดภาพและแปลงเป็นสีเทาคู่:

I = imread('hw.jpg');
I = rgb2gray(I);
I = double(I);

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

กรองโดยใช้ความแตกต่างของเคอร์เนล Gaussian และทำให้ปกติ:

J = imgaussian(I,1.5) - imgaussian(I,0.5);
J = J - min(J(:));
J = J / max(J(:));

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

คำนวณเกณฑ์และทำให้ 010101:

T = J > graythresh(J);

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


4

นี่คือรหัส Matlab ที่ดีสำหรับการปรับเปลี่ยนการกำหนดเกณฑ์ขั้นสูง: http://www.mathworks.com/matlabcentral/fileexchange/8647-local-adaptive-thresholding


โอ๊ะ! ต้องใช้กล่องเครื่องมือการประมวลผลภาพ : - /
Spacey

จริง ขออภัยถ้าคุณไม่มี แต่ DIPImage เป็น Image Tolbox สำหรับ Matlab ฟรี diplib.org/documentationมันมีวิธีการไม่กี่วิธีสำหรับการกำหนดเกณฑ์ขั้นต่ำ (ส่วนการตรวจสอบการแบ่งส่วน) และคุณยังสามารถดำเนินการทางสัณฐานวิทยาทั้งหมดเช่นการปิด นักพัฒนายังมีบล็อกcb.uu.se/~cris/blog/index.php/archives/tag/matlab
MyCarta

0

ฉันจะลองใช้รหัสนี้ แต่ฉันไม่มีคำตอบที่ถูกต้อง ...

clc;
clear;
x=imread('base2.jpg');
size(x);
x=imresize(x,[500 800]);
figure;
imshow(x);
title('original image');
z=rgb2hsv(x);       %extract the value part of hsv plane
v=z(:,:,3);
v=imadjust(v);
m = mean(v(:))
s=std(v(:))
k=-2;
value=m+ k*s;
temp=v;
for p=1:1:500
    for q=1:1:800
        pixel=temp(p,q);
        if(pixel>value)
            temp(p,q)=1;
        else
            temp(p,q)=0;
        end
    end
end
figure;
imshow(temp);
title('result by niblack');
% k=kittlerMet(g);
% figure;
% imshow(k);
% title('result by kittlerMet');

val2=m*(1+.1*((s/128)-1));
t2=v;
for p=1:1:500
for q=1:1:800
    pixel=t2(p,q);
    if(pixel>value)
        t2(p,q)=1;
    else
        t2(p,q)=0;
    end
end

end
figure;
imshow(t2);
title('result by sauvola');

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

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


2
หากนี่เป็นการตอบคำถามโปรดอธิบายว่าคุณกำลังทำอะไรและเพราะอะไร
Matt L.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.