Scala Spark Structured Streaming:导入图像文件以创建简单的ML应用程序

Scala Spark Structured Streaming:导入图像文件以创建简单的ML应用程序,scala,image-processing,spark-structured-streaming,Scala,Image Processing,Spark Structured Streaming,我想构建一个结构化流应用程序,其目的是从URL检索图像,并构建一个非常简单的ML模型,该模型将根据图像的内容进行分类 我有一个URL(),它每X个时间单位用一个新图像更新一次。我的目标是首先存储这些图像,或者直接使用readStream对象导入它们(如果可能的话)。我知道,由于Spark 2.X,我们可以直接使用图像格式将内容读入数据帧。我在不同的方法之间犹豫不决: 使用消息的总线解决方案(如Kafka)将生成我的内容供Spark使用,我认为这并不坏,因为Kafka可用于复制文件,因此数据丢失

我想构建一个结构化流应用程序,其目的是从URL检索图像,并构建一个非常简单的ML模型,该模型将根据图像的内容进行分类

我有一个URL(),它每X个时间单位用一个新图像更新一次。我的目标是首先存储这些图像,或者直接使用readStream对象导入它们(如果可能的话)。我知道,由于Spark 2.X,我们可以直接使用
图像
格式将内容读入数据帧。我在不同的方法之间犹豫不决:

  • 使用消息的总线解决方案(如Kafka)将生成我的内容供Spark使用,我认为这并不坏,因为Kafka可用于复制文件,因此数据丢失更轻
  • 直接使用readStream对象来读取图像(这就是我试图做的,见下文)
我的下一个Scala代码的目的只是试图显示图像的内容,但是当我使用
spark shell
测试它时,它会抛出不同的错误,我将在下面代码的相应部分对错误进行注释

scala> val url = "http://129.102.240.235/extraits/webcam/webcam.jpg"
url: String = http://129.102.240.235/extraits/webcam/webcam.jpg

scala> spark.sparkContext.addFile(url)

scala> val image_df = spark.read.format("image").load("file://"+SparkFiles.get("webcam.jpg"))
image_df: org.apache.spark.sql.DataFrame = [image: struct<origin: string, height: int ... 4 more fields>]

scala> image_df.select("image.origin").show(false)
19/10/25 13:33:26 ERROR Executor: Exception in task 0.0 in stage 1.0 (TID 1)
org.apache.spark.SparkException: File /tmp/spark-28741963-fd2d-44c2-8a6b-a489fdaae96d/userFiles-95b99fde-a1e2-4da6-9a17-382bfd2292c4/webcam.jpg exists and does not ma
tch contents of http://129.102.240.235/extraits/webcam/webcam.jpg
scala>val url=”http://129.102.240.235/extraits/webcam/webcam.jpg"
url:字符串=http://129.102.240.235/extraits/webcam/webcam.jpg
scala>spark.sparkContext.addFile(url)
scala>val image_df=spark.read.format(“image”).load(“文件:/”+SparkFiles.get(“webcam.jpg”))
image\u df:org.apache.spark.sql.DataFrame=[image:struct]
scala>image\u df.select(“image.origin”).show(false)
19/10/25 13:33:26错误执行者:任务0.0在阶段1.0(TID 1)中出现异常
org.apache.spark.sparkeexception:File/tmp/spark-28741963-fd2d-44c2-8a6b-a489fdaae96d/userFiles-95b99fde-a1e2-4da6-9a17-382bfd2292c4/webcam.jpg存在且不存在
目录http://129.102.240.235/extraits/webcam/webcam.jpg
我还尝试使用readStream:

scala> val scheme = " origin STRING, height INT, width INT, nChannels INT, mode INT, data BINARY"
scheme: String = " origin STRING, height INT, width INT, nChannels INT, mode INT, data BINARY"

scala> val image_df = spark.readStream.format("image").schema(scheme).load("file://"+SparkFiles.get("webcam.jpg"))
image_df: org.apache.spark.sql.DataFrame = [origin: string, height: int ... 4 more fields]

scala> val query_show = image_df.collect.foreach(println).writeStream.format("console").start()
<console>:26: error: value writeStream is not a member of Unit
       val query_show = image_df.collect.foreach(println).writeStream.format("console").start()

// Based on what I red on StackO question, I suppose that this error might be caused because 
// .writeStream should be on the next line, so I tried to put it on 2 lines but..

scala> val query_show = image_df.collect.foreach(println).
     |   writeStream.format("console").start()
<console>:27: error: value writeStream is not a member of Unit
possible cause: maybe a semicolon is missing before `value writeStream'?
         writeStream.format("console").start()

// Also tried without declaring query_show but returns the same error..
// I know that if I make it work I will have to add query_show.awaitTermination()
scala>val scheme=“原始字符串、高度INT、宽度INT、通道INT、模式INT、数据二进制”
scheme:String=“原始字符串、高度INT、宽度INT、通道INT、模式INT、数据二进制”
scala>val image_df=spark.readStream.format(“image”).schema(scheme.load(“文件:/”+SparkFiles.get(“webcam.jpg”))
image\u df:org.apache.spark.sql.DataFrame=[来源:字符串,高度:int…4个其他字段]
scala>val query\u show=image\u df.collect.foreach(println.writeStream.format(“控制台”).start()
:26:错误:值writeStream不是单元的成员
val query_show=image_df.collect.foreach(println.writeStream.format(“控制台”).start()
//根据我对StackO问题的回答,我想这个错误可能是因为
//.writeStream应该在下一行,所以我尝试将其放在两行,但是。。
scala>val query\u show=image\u df.collect.foreach(println)。
|writeStream.format(“控制台”).start()
:27:错误:值writeStream不是单元的成员
可能原因:“value writeStream”之前可能缺少分号?
writeStream.format(“控制台”).start()
//也尝试了不声明query\u show,但返回相同的错误。。
//我知道如果我让它工作,我将不得不添加query_show.waiting()

任何关于调试此代码的帮助或构建我的流媒体管道的想法都将不胜感激

我设法找到一种方法,使用“图像”格式显示我的数据框红色。 我分两步完成:
1/运行将从URL保存jpg图像的Python脚本,该脚本为:

导入urllib.request
进口舒蒂尔
文件名=“~/didi/bpi spark/images”
url=”http://129.102.240.235/extraits/webcam/webcam.jpg"
将urllib.request.urlopen(url)作为响应,将(文件名'ab')作为out_文件打开:
copyfileobj(响应,输出文件)
2/然后,使用spark shell,我刚刚执行了这两行:

val image\u df=spark.read.format(“image”)。选项(“推断模式”,true)。加载(“bpi spark/images”)。选择($“image.origin”、$“image.height”、$“image.width”、$“image.mode”、$“image.data”)
scala>image_df.show()
+--------------------+------+-----+----+--------------------+
|原点|高度|宽度|模式|数据|
+--------------------+------+-----+----+--------------------+
|file:///home/niki...|480 | 720 | 16 |[3C 3D 39 3C 3D 3|
+--------------------+------+-----+----+--------------------+