DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible

extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible {
    /// The textual representation used when written to an output stream, which includes whether the result was a
    /// success or failure.
    public var description: String {
        return result.debugDescription
    }

    /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
    /// response, the temporary and destination URLs, the resume data, the response serialization result and the
    /// timeline.
    public var debugDescription: String {
        var output: [String] = []

        output.append(request != nil ? "[Request]: \(request!.httpMethod ?? "GET") \(request!)" : "[Request]: nil")
        output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
        output.append("[TemporaryURL]: \(temporaryURL?.path ?? "nil")")
        output.append("[DestinationURL]: \(destinationURL?.path ?? "nil")")
        output.append("[ResumeData]: \(resumeData?.count ?? 0) bytes")
        output.append("[Result]: \(result.debugDescription)")
        output.append("[Timeline]: \(timeline.debugDescription)")

        return output.joined(separator: "\n")
    }
}

     
第七步是有叫完整包含在空蒙尚免受认为是天幕的稍区域加加至天上中。

protocol Response

protocol Response {
    /// The task metrics containing the request / response statistics.
    var _metrics: AnyObject? { get set }
    mutating func add(_ metrics: AnyObject?)
}

extension Response {
    mutating func add(_ metrics: AnyObject?) {
        #if !os(watchOS)
            guard #available(iOS 10.0, macOS 10.12, tvOS 10.0, *) else { return }
            guard let metrics = metrics as? URLSessionTaskMetrics else { return }

            _metrics = metrics
        #endif
    }
}

// MARK: -

@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
extension DefaultDataResponse: Response {
#if !os(watchOS)
    /// The task metrics containing the request / response statistics.
    public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
#endif
}

@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
extension DataResponse: Response {
#if !os(watchOS)
    /// The task metrics containing the request / response statistics.
    public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
#endif
}

@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
extension DefaultDownloadResponse: Response {
#if !os(watchOS)
    /// The task metrics containing the request / response statistics.
    public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
#endif
}

@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
extension DownloadResponse: Response {
#if !os(watchOS)
    /// The task metrics containing the request / response statistics.
    public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
#endif
}

上边的协议中发生一个特性和一个办法,如果当商量被落实了本人之道,那么实现该协议的目标好毫不实现该谋被的艺术。以上面介绍的特性中
_metrics是发源该协议的性能。在上方的初始化方法吃吗未尝_metrics这一项

每当swift中,当多独目标公用一个特性或者措施时,就得设想协议了。

每当这里比如上面的用法,举个大概的例证。

public struct Person {
    public var name: String
    public var age: UInt
    var _hobby: String?

    init(name: String, age: UInt) {
        self.name = name
        self.age = age
    }
}

var person = Person(name: "James", age: 30)
print(person.name)

person.name = "Bond"
print(person.name)

var person1 = person
print(person1.name)

person1.name = "Rose"
print(person1.name)
print(person.name)



protocol Hobbyable {
    var _hobby: String? { get set }
    mutating func addHobby(_ hobby: String?)
}

extension Hobbyable {
    mutating func addHobby(_ hobby: String?) {
        _hobby = hobby
    }
}

extension Person: Hobbyable {
    var hobby: String? {
        return _hobby
    }
}

person1.addHobby("Books")
print(person1.hobby ?? "")

    整个工艺流程的示意图如下所示:

DataResponse: CustomStringConvertible, CustomDebugStringConvertible

DataResponse实现了CustomStringConvertible和CustomDebugStringConvertible协议,因此得以自定义DataResponse的打印信息。

咱俩也可为咱们模型实现即片独协议,在代码调试之上,打印出详细的信息,比打断点来查看效率又胜。

extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible {
    /// The textual representation used when written to an output stream, which includes whether the result was a
    /// success or failure.
    public var description: String {
        return result.debugDescription
    }

    /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
    /// response, the server data, the response serialization result and the timeline.
    public var debugDescription: String {
        var output: [String] = []

        output.append(request != nil ? "[Request]: \(request!.httpMethod ?? "GET") \(request!)" : "[Request]: nil")
        output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
        output.append("[Data]: \(data?.count ?? 0) bytes")
        output.append("[Result]: \(result.debugDescription)")
        output.append("[Timeline]: \(timeline.debugDescription)")

        return output.joined(separator: "\n")
    }
}

               原图                                    何的去雾                             本文结果(SkyPresrve
=100)

DownloadResponse

夫呢未尝什么好说的,直接上代码:

/// Used to store all data associated with a serialized response of a download request.
public struct DownloadResponse<Value> {
    /// The URL request sent to the server.
    public let request: URLRequest?

    /// The server's response to the URL request.
    public let response: HTTPURLResponse?

    /// The temporary destination URL of the data returned from the server.
    public let temporaryURL: URL?

    /// The final destination URL of the data returned from the server if it was moved.
    public let destinationURL: URL?

    /// The resume data generated if the request was cancelled.
    public let resumeData: Data?

    /// The result of response serialization.
    public let result: Result<Value>

    /// The timeline of the complete lifecycle of the request.
    public let timeline: Timeline

    /// Returns the associated value of the result if it is a success, `nil` otherwise.
    public var value: Value? { return result.value }

    /// Returns the associated error value if the result if it is a failure, `nil` otherwise.
    public var error: Error? { return result.error }

    var _metrics: AnyObject?

    /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization.
    ///
    /// - parameter request:        The URL request sent to the server.
    /// - parameter response:       The server's response to the URL request.
    /// - parameter temporaryURL:   The temporary destination URL of the data returned from the server.
    /// - parameter destinationURL: The final destination URL of the data returned from the server if it was moved.
    /// - parameter resumeData:     The resume data generated if the request was cancelled.
    /// - parameter result:         The result of response serialization.
    /// - parameter timeline:       The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
    ///
    /// - returns: The new `DownloadResponse` instance.
    public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        temporaryURL: URL?,
        destinationURL: URL?,
        resumeData: Data?,
        result: Result<Value>,
        timeline: Timeline = Timeline())
    {
        self.request = request
        self.response = response
        self.temporaryURL = temporaryURL
        self.destinationURL = destinationURL
        self.resumeData = resumeData
        self.result = result
        self.timeline = timeline
    }
}

 
 图片 1  图片 2

总结

由于文化水平有限,如有不当,还为指出

  其中SkyPresrve就接近于论文的永恒透射率值,是用户指定的,在上式中,若Sky[255],即完全属于天空,则改点的透射率即为固定值,若Sky[Y]=0,即完全无属天空,计算式的价不移,不影响健康去雾。

前言

以列首稿子的题词部分,我还见面把自家看的本篇最要害的情提前摆一下。我再也想和大家分享这些顶级框架在筹划及编码层次究竟有哪大之地方?当然,这些理解为都是冲自身自己的懂得。难免有局限性。

当我们统筹了一个Request的当儿,我们定使处理服务器返回的应数据。在Alamofire源码解读系列(一)之概述和下中,我们早就出口过,Alamofire中管Request分为了4接近:

  • DataRequest
  • DownloadRequest
  • UploadRequest
  • StreamRequest

Alamofire中Request可以采用链式访问:

Alamofire.request("https://httpbin.org/get")
    .responseString { response in
        print("Response String: \(response.result.value)")
    }
    .responseJSON { response in
        print("Response JSON: \(response.result.value)")
    }

可知实现链式访问的原理就是是每个函数的归来值都是Self。那么以上头的代码中,虽然response的讳都一致,但连无是相同种类。

坐起4惨遭不同之Request类型,StreamRequest我们先不提,对于UploadRequest来说,服务器响应的数码比较简单,就应一个结出就是实施,因此无欲针对其的Response专门展开打包。因此,Alamofire设计了2受同之相对应的Response类型,他们分别是:

  • DefaultDataResponse / DataResponse
  • DefaultDownloadResponse / DataResponse

那,如果我们运用下的代码获取响应数据:

// Response Handler - Unserialized Response
func response(
    queue: DispatchQueue?,
    completionHandler: @escaping (DefaultDataResponse) -> Void)
    -> Self

取之凡未曾经序列化后底数,如果使用了没有序列化的response方法,返回的饶是含Default始发的响应者,比如DefaultDataResponse,DefaultDownloadResponse。如果以了序列化的response方法,返回的就算是DataResponse或者DataResponse。

旋即证明了啊?
在程序的计划性规模达到,这种光景呼应的手段能够吃代码更好明。就如于品种中未可知管具有的参数都置于一个模型中一致。

拿DefaultDataResponse /
DataResponse来比喻,DataResponse基本上就比较DefaultDataResponse多了一个趋势后底数性。

还有一些如提取一下,先借要每个Request都得让排化为JSON,或者String。这些还属于序列化Response的限。序列化成功后,保存数据的容器应发一个种,而此类别又是可转移之,在本篇文章下面的始末中会指出泛型的施用方法。

 

DataResponse<Value>

DataResponse<Value>比上的DefaultDataResponse多了一个result属性,该属性存储了序列化后的多寡。它的路是
Result<Value>,关于Result的详情内容,请圈就篇文章Alamofire源码解读系列(五)之结果封装(Result)

/// Used to store all data associated with a serialized response of a data or upload request.
public struct DataResponse<Value> {
    /// The URL request sent to the server.
    public let request: URLRequest?

    /// The server's response to the URL request.
    public let response: HTTPURLResponse?

    /// The data returned by the server.
    public let data: Data?

    /// The result of response serialization.
    public let result: Result<Value>

    /// The timeline of the complete lifecycle of the request.
    public let timeline: Timeline

    /// Returns the associated value of the result if it is a success, `nil` otherwise.
    public var value: Value? { return result.value }

    /// Returns the associated error value if the result if it is a failure, `nil` otherwise.
    public var error: Error? { return result.error }

    var _metrics: AnyObject?

    /// Creates a `DataResponse` instance with the specified parameters derived from response serialization.
    ///
    /// - parameter request:  The URL request sent to the server.
    /// - parameter response: The server's response to the URL request.
    /// - parameter data:     The data returned by the server.
    /// - parameter result:   The result of response serialization.
    /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
    ///
    /// - returns: The new `DataResponse` instance.
    public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        data: Data?,
        result: Result<Value>,
        timeline: Timeline = Timeline())
    {
        self.request = request
        self.response = response
        self.data = data
        self.result = result
        self.timeline = timeline
    }
}

  对当下几乎独步骤我进行了粗糙的点评吧。

链接

Alamofire源码解读系列(一)之概述和采取
简书—–博客园

Alamofire源码解读系列(二)之错误处理(AFError)
简书—–博客园

Alamofire源码解读系列(三)之通知处理(Notification)
简书—–博客园

Alamofire源码解读系列(四)之参数编码(ParameterEncoding)
简书—–博客园

Alamofire源码解读系列(五)之结果封装(Result)
简书—–博客园

Alamofire源码解读系列(六)之Task代理(TaskDelegate)
简书—–博客园

Alamofire源码解读系列(七)之网监控(NetworkReachabilityManager)
简书—–博客园

Alamofire源码解读系列(八)之安全策略(ServerTrustPolicy)
简书—–博客园

     
当|I(x)-A|<k时,认为是区域或者是天,重新计算透射率(增加透射率),|I(x)-A|>k处,则觉得是称暗通道先验的区域,透射率不转换。

本篇主要带来Alamofire中Response的解读

         
 图片 3

DefaultDataResponse

DefaultDataResponse用于存储data或upload请求情况下之有着无序列化的数目。那么以Alamofire中对此服务器的应主要关心的数额产生脚几只:

  • request: URLRequest? 表示该应来源于那个请求
  • response: HTTPURLResponse? 服务器返回的响应
  • data: Data? 响应数据
  • error: Error? 在恳求被恐怕出的错
  • timeline: Timeline 请求的时线包,这个会于继承的篇章被讲
  • _metrics: AnyObject? 包含了请求和响应的统计信息

代码如下:

 /// The URL request sent to the server.
    public let request: URLRequest?

    /// The server's response to the URL request.
    public let response: HTTPURLResponse?

    /// The data returned by the server.
    public let data: Data?

    /// The error encountered while executing or validating the request.
    public let error: Error?

    /// The timeline of the complete lifecycle of the request.
    public let timeline: Timeline

    var _metrics: AnyObject?

相似的话,在swift中,如果只是是为保存数据,那么相应拿此看似设计成struct。struct是
值传递,因此对数据的操作更安全。除定义需要保留的数额性后,必须设计一个符合要求的构造函数。

 /// Creates a `DefaultDataResponse` instance from the specified parameters.
    ///
    /// - Parameters:
    ///   - request:  The URL request sent to the server.
    ///   - response: The server's response to the URL request.
    ///   - data:     The data returned by the server.
    ///   - error:    The error encountered while executing or validating the request.
    ///   - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
    ///   - metrics:  The task metrics containing the request / response statistics. `nil` by default.
    public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        data: Data?,
        error: Error?,
        timeline: Timeline = Timeline(),
        metrics: AnyObject? = nil)
    {
        self.request = request
        self.response = response
        self.data = data
        self.error = error
        self.timeline = timeline
    }

     
还有一样步,论文也干了,就是这些校正的步调都须以refine阶段前举行,简单的说,就是要在进展导向滤波前召开。这样用导向滤波的坦功能,可以将圆和非天空分界部位的免平坦现象肯定水准上弥补掉);

DefaultDownloadResponse

DefaultDownloadResponse保存的是生充斥任务之数目。有3独特性需要举行一下介绍:

  • temporaryURL: URL? 现在成后,数据会给保存在这个临时URL中
  • destinationURL: URL?
    目标URL,如果安了拖欠属性,那么文件会复制到拖欠URL中
  • resumeData: Data?
    表示可复原的多寡,对于下载任务,如果以某种原因下载中断了,或破产了,可以行使该数据恢复之前的下载

其余的内容及上边介绍的情节没什么特别的地方,就大概的拿代码来上来了:

/// Used to store all data associated with an non-serialized response of a download request.
public struct DefaultDownloadResponse {
    /// The URL request sent to the server.
    public let request: URLRequest?

    /// The server's response to the URL request.
    public let response: HTTPURLResponse?

    /// The temporary destination URL of the data returned from the server.
    public let temporaryURL: URL?

    /// The final destination URL of the data returned from the server if it was moved.
    public let destinationURL: URL?

    /// The resume data generated if the request was cancelled.
    public let resumeData: Data?

    /// The error encountered while executing or validating the request.
    public let error: Error?

    /// The timeline of the complete lifecycle of the request.
    public let timeline: Timeline

    var _metrics: AnyObject?

    /// Creates a `DefaultDownloadResponse` instance from the specified parameters.
    ///
    /// - Parameters:
    ///   - request:        The URL request sent to the server.
    ///   - response:       The server's response to the URL request.
    ///   - temporaryURL:   The temporary destination URL of the data returned from the server.
    ///   - destinationURL: The final destination URL of the data returned from the server if it was moved.
    ///   - resumeData:     The resume data generated if the request was cancelled.
    ///   - error:          The error encountered while executing or validating the request.
    ///   - timeline:       The timeline of the complete lifecycle of the request. `Timeline()` by default.
    ///   - metrics:        The task metrics containing the request / response statistics. `nil` by default.
    public init(
        request: URLRequest?,
        response: HTTPURLResponse?,
        temporaryURL: URL?,
        destinationURL: URL?,
        resumeData: Data?,
        error: Error?,
        timeline: Timeline = Timeline(),
        metrics: AnyObject? = nil)
    {
        self.request = request
        self.response = response
        self.temporaryURL = temporaryURL
        self.destinationURL = destinationURL
        self.resumeData = resumeData
        self.error = error
        self.timeline = timeline
    }
}

图片 4

     
  图片 5

     
另外关于大气光值A的计算,论文提出了以抱的天幕部位的像素的平均值作为A,这也是蛮合理的,但是于实际处理时,针对有些完全没空部分的图像,可能检测到的苍天区域大粗(明显属于误检,但是程序不理解之),这个时刻因之也大气光值,也是免客观的。为者,我之处理方式先计算天空部位计算的A值,然后于检测天空像素占整个图像的比重,如果比例小于5%,则还是因为何凯明那种计算A的措施展开。

 
 图片 6  图片 7

     
如果K取值为0,则相当给旧的透射率公式。

  

  即在HSV空间,对V分量进行CLAHE增强,然后于更换到RGB空间,这种方法对小图像确实发好明确的增高效能,但是来头图或还要见面增强噪音,因此要冲实际状况选择性的拍卖吧。

 

  示例程序:http://files.cnblogs.com/Imageshop/HazeRemovalWithSkyRecognition.rar

     
得到天空区域后,原文作者用天空区域之透射率图统一之安装成了一个固定值,我看这么不好,还是应因具体的价值做适当的修正。
在自己上述的操作着,得到的圆去区域是同一合蒙版图,某个点并不一定是一点一滴属于天空要全无属。因此,我虽得因这值来+
暗通道求得的价值进行一下Alpha掺杂,如下所示:

   
 2、求灰度图像的梯度信息(其实就是得为此常用之片边缘检测算子实现);

图片 8 图片 9 图片 10

   
 图片 11  图片 12 图片 13

     
上面的做法是较为合理的,因为一般景象下非常气光A的取值和天幕部分该是甚类似的,而那些符合暗通道的地方则离家天空,关于这算法的职能,我在我的《Single
Image Haze Removal Using Dark Channel
Prior》一柔和被图像去雾算法的法则、实现、效果(速度而实时)平轻柔之实例工程中都提供了测试程序。

   
 图片 14

 

 
 图片 15
  图片 16

      第一首稿子增加了一个可控参数K,
用来调节每个像素处的透射率:

     
第六步是为防止有些漏检点,把以天空区域广的有诸如从在进一步进行识别,符合条件的虽然加以至天区域受到。

            稍作去噪                                 初步天空识别                           
          进行羽化

      2、Single image dehazing Algorithms
based on sky region segmentation, 2013  王广义
 哈尔滨工业大学(这首文章似乎要交全校里才能够下载);

   
 4、按照设定梯度阈值和亮度阈值对梯度信息进行区分;

  有以上比较可见,在保安了昊之下,和皇上交接的地方的去雾程度吗相当的有弱化。

   
 图片 17

 

     
作为对照,我们以为来几幅图的圆之辨认功能:

     
 第二首文章的笔触则是进行天空分割。对细分后底有数有透射率做不同的拍卖,那么这个的重要就是在于皇上特征的领到。作者原文是经过以下几只步骤来贯彻的。

     
第三步对起来的境界进行下小范围之壮大。

  一片黑,因此,完全不影响结果。

  DarkChannel[Y]= (SkyPresrve *
Sky[Y] + DarkChannel[Y] * (255 – Sky[Y])) / 255 ;    

     
作为比,我们深受有直接用何的点子实现之效果以及用天空识别术处理的相比效果:

     
第四步对细分后底觊觎的每个联通区域统计其本来图像于对许位置的像素的平分亮度,如果过量阈值T则保留,T这里作者取0.81,对诺整数205横。

              原图                                    灰度图                                  梯度信息

图片 18  图片 19 图片 20

     我之做法是: 

  为了增进速度,也可以使用自于何那篇论文的辨析的博文被的方法,进行下采样处理,然后于达到采样。

   
  图片 21 图片 22 图片 23

1、 改善的因暗原色先验的图像去雾算法
作者: 蒋建国\侯天峰\齐美彬  
合肥工业大学 2011。

  图片 24 图片 25  图片 26

   
  图片 27 图片 28 图片 29

     
第一步我觉得极有价,直接以原本数据判断天空不是死好做,作者考察到天上部分完全来说是较平缓的,也就是是附近像素之间转变不要命,因此用梯度来表示虽然更便于辨认,梯度值更小则表明图像那无异块越滑。

 
 在舆论的末尾,作者为关系了去雾的图像显示比暗,为这个,做了瞬间甩卖:

   
 3、对梯度信息进行适当的去噪和滤波;

   
 图片 30

   
 图片 31  图片 32 图片 33

     
第五步取符合第四步条件的极酷的联通区域作为识别的天区域。

   
 个人认为,除了第一步、第二步、第四步有必要他,其他的非待这样处理。特别是第五步之拍卖会招天空部位的漏检。比如下面的流水线示意图的原图,如果就此上述办法自然会招致左上角处小片天空完全不见不见。另外一个问题即,联通区域之计还是比较耗时的。

   
 5、对分后底觊觎进行高斯羽化处理(可选的)。

     
在藏的几乎栽去雾算法中,包括何凯明的暗通道去雾、Tarel的因中值滤波的去雾以及部分根据其他边缘保留的计被,都发一个普遍存在的题材:即对天部分处理的糟糕,天空往往会现出于充分的面积的纹理及分块现象。究其根本原因,还是以天部位多是匪抱暗通道去雾先验这个前决条件的。目前,针对当下同样题目,我搜寻到的要出以下几篇稿子展开了拍卖:

   
 1、将图像转换为灰度:这里呢保存更多的边缘信息,可以考虑采取所有对比度保留功能要显著性保留功能的有些去色算法。

 
 图片 34

****************************笔者:
laviewpbt   时间: 2014.8.12    联系QQ:  33184777
转载请保留本行信息**********************

 对于那些基本不设有天空之觊觎,检测的结果如下:

     
第二步则设定一个阈值来初步判断某处是否属于天空,这个阈值作者取之是0.02,量化到unsigned
char范围虽然着力对应5。