风筝
发表于: 2017-7-18 16:35:24 | 显示全部楼层

平板扫描仪通常使用三排CCD传感器(RGB)来捕获直接放置在玻璃床顶部的图像。当CCD阵列从图像的一端扫描到另一端时,形成数字化的彩色图像。所以用类似的方法,我们可以使用一个光敏设备通过光栅扫描一次一个像素来捕获整个图像。现在我有一个HP 7044A X-Y刻录机,我可以使用它的X / Y伺服机构与一个合适的传感器来构建一个单通道的像素扫描仪。


最简单的传感器是光电二极管或CdS光电管。为了捕获灰度图像,可以使用这些传感器中的任何一个。为了捕获彩色图像,我们需要一个能够识别每个像素的RGB分量的传感器。为此我使用了一种廉价的基于TCS34725的彩色传感器模块。

RGBSensor.jpg


我将颜色传感器安装到绘图仪的笔架上,并调整高度,以便当笔向下时,传感器距离表面大约4至5毫米。这应该允许所获得的图像更加聚焦,因为较少的杂散光将落在任何给定像素位置处的传感器上。理想情况下,我可以将镜头安装在彩色传感器的前面,但我没有任何合适的镜头用于此目的。


以下图片展示了实验设置。我使用Arduino Due开发板控制绘图仪。 Arduino Due是非常方便的,因为它有两个12位DAC来控制绘图仪的X和Y运动。

scanner1.jpg


scanner2.jpg


对于下面的代码,我使用Arduino的Adafruit的TCS34725库。 TCS34725传感器的一个问题是,为了更高的颜色分辨率,由于较长的积分时间,捕获时间相当长。不幸的是,这种图像扫描速度有所减慢。我可以使用更短的积分时间,但是颜色分辨率会大大降低。所以在下面的示例代码中,我使用了128×128的图像大小,步长为32,并使用了相对较长的积分时间。即使在这个分辨率(128×128),仍然需要近一个小时来完成扫描单个图像。以全分辨率(4096×4096)扫描相同的图像需要一个多月,这是不切实际的。


每个像素位置处的捕获的RGB值将被发送到串行控制台,并保存到文本文件中。

  1. #include <Wire.h>
  2. #include "Adafruit_TCS34725.h"

  3. Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_154MS, TCS34725_GAIN_4X);

  4. int imageSize = 128;
  5. int stepSize = 4096 / imageSize;

  6. void setup(void) {
  7.   Serial.begin(9600);
  8.   analogWriteResolution(12);
  9.   
  10.   delay(500);      
  11.       
  12.   if (tcs.begin()) {   
  13.     Serial.println("Start>>");
  14.     runScan();
  15.   } else {
  16.     Serial.println("TCS34725 not detected");
  17.   }
  18. }

  19. void runScan()
  20. {
  21.   uint16_t r,g,b,c;
  22.   
  23.   int x,y;
  24.   
  25.   for (x=0; x< 4096; x+=stepSize) {
  26.     analogWrite(DAC0,x);
  27.     delay(500);
  28.     for (y=0; y< 4096; y+=stepSize) {
  29.       analogWrite(DAC1,y);
  30.       delay(10);
  31.       tcs.getRawData(&r, &g, &b, &c);
  32.       Serial.print(r);Serial.print(", ");
  33.       Serial.print(g);Serial.print(", ");
  34.       Serial.print(b);Serial.print(", ");      
  35.     }
  36.     Serial.println();
  37.   }
  38. }

  39. void loop(void) {
  40. }
复制代码

以下MATLAB代码读取文本文件中捕获的数据,将RGB分量分离为相应的矩阵,最后将三个颜色通道组合成单个彩色图像。

  1. ftoread = 'img.txt';
  2. fid = fopen(ftoread);
  3. M = textscan(fid, '%f', 'Delimiter',',');
  4. fclose(fid);

  5. rawImg = M{1};

  6. r1 = (rawImg - min(rawImg))./max(rawImg)*3;

  7. R=r1(1:3:length(r1));
  8. G=r1(2:3:length(r1));
  9. B=r1(3:3:length(r1));
  10. r=reshape(R, [128, 128]);
  11. g=reshape(G, [128, 128]);
  12. b=reshape(B, [128, 128]);

  13. rgbImg=cat(3, r, g, b);
  14. imshow(rgbImg);
复制代码

以下是一个实验运行的输出数据。正如你所看到的,尽管分辨率比较低,原始图像中的所有功能都被正确捕获,尽管扫描图像有一些颜色精度问题。再现颜色的不准确性可归因于传感器本身和板载白光LED的光谱限制。

scannedimg.jpg


本文翻译自:http://www.kerrywong.com/2017/07 ... ngle-pixel-scanner/,感谢Kerry D. Wong做出的贡献。如有错漏,敬请指正。

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1482



手机版|

GMT+8, 2024-5-2 05:43 , Processed in 0.036293 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表