jpg毁损检测思路

基于libjpeg保存jpg图像或者读取图像时,特别是再存储大尺寸图像时,一个问题特别突出。即图像存储明明毁损了,但是调用存储的函数直接再控制台输出警告信息,但是没有返回值或者异常可供捕获。造成毁损的原因不明。只能推测是libjpeg多线程存储问题。其中图像存在 JWRN_JPEG_EOF 问题时特别致命。因为图像从某一个节点之后信息全部无效。以下是最终算法能够捕获的毁损。

JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")

JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")

JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")

JWRN_JPEG_EOF是核心要解决的问题。 后俩者是最后优化代码时剩余部分比较复杂,时间有限,保留代码顺带检测。

动手解决之前思路:基于libjpeg库,屏蔽掉无关代码,将警告改为异常抛出。捕获并产生相应记录信息。因为是提前终止,因此期待直接从文件头获取文件长度和实际文件长度比较,直接得到判定。

实际解决思路:

1.借鉴opencv的库进行libjpeg重新改写。

2.将libjpeg里面一些C代码更改为C++代码,并消除一些与检测无关代码,提高检测效率。

3.跟踪JWRN_JPEG_EOF 出现位置,梳理前后代码。发现动手前的思路存在缺失。并不能直接获取文件长度进行比较。实际jpg判断该问题是基于段,每次循环前判定当前读取字节数 < 该段字节总数。是的话一次读取固定长度(jpg代码有具体数值)。当读取到字节数目<固定长度,就会进行判定 抛出俩种异常其中一种 就是“JWRN_JPEG_EOF”。 原始libjpg代码如下:

 1 METHODDEF(boolean)
 2     fill_input_buffer (j_decompress_ptr cinfo)
 3 {
 4     my_src_ptr src = (my_src_ptr) cinfo->src;
 5     size_t nbytes;
 6 
 7     nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
 8 
 9     if (nbytes <= 0) {
10         if (src->start_of_file)    /* Treat empty input file as fatal error */
11             ERREXIT(cinfo, JERR_INPUT_EMPTY);
12         WARNMS(cinfo, JWRN_JPEG_EOF);
13         /* Insert a fake EOI marker */
14         src->buffer[0] = (JOCTET) 0xFF;
15         src->buffer[1] = (JOCTET) JPEG_EOI;
16         nbytes = 2;
17     }
18 
19     src->pub.next_input_byte = src->buffer;
20     src->pub.bytes_in_buffer = nbytes;
21     src->start_of_file = FALSE;
22 
23     return TRUE;
24 }
 1 METHODDEF(boolean)
 2     fill_mem_input_buffer (j_decompress_ptr cinfo)
 3 {
 4   static const JOCTET mybuffer[4] = {
 5     (JOCTET) 0xFF, (JOCTET) JPEG_EOI, 0, 0
 6   };
 7 
 8   /* The whole JPEG data is expected to reside in the supplied memory
 9    * buffer, so any request for more data beyond the given buffer size
10    * is treated as an error.
11    */
12   WARNMS(cinfo, JWRN_JPEG_EOF);
13 
14   /* Insert a fake EOI marker */
15 
16   cinfo->src->next_input_byte = mybuffer;
17   cinfo->src->bytes_in_buffer = 2;
18 
19   return TRUE;
20 }

4.找到查错代码后更改自定义代码。我理解不够没有重新书写代码,而是通过剥离出来的opencv的jpeg库调用。然后跟踪执行路径,把执行路径中的函数标记出来,重新写成自己的函数,然后调用。

5.最终效果:使用opencv读取图片会报 JWRN_JPEG_EOF,我这边也会报。执行时间:16000*8192彩色图像,用imread执行时间3~5s,用我更改后的libjpeg库只需要0.2~0.3s(这边耗时主要霍夫编解码上面。因为指针遍历有部分再霍夫编解码上,赶时间没有细究。如果消除的话就是 10ms以内级别操作)。

 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2019-05-10这样直接改某些情况下会触发野指针。暂不清楚引起得原因。因为此时有问题的图片能打开,能看。不确定是真的文件存在问题,还是写的算法有问题。所以最好加异常捕获代码。

转载于:https://www.cnblogs.com/PiaoLingJiLu/p/9145505.html

### 关于相位检测坏点及其修复方法 #### 相位检测坏点概述 相位检测技术依赖于相机传感器上的特定像素来捕捉来自不同方向的光线并计算其相位差。当这些用于相位检测的像素出现故障时,可能会导致对焦性能下降甚至完全失效。这种现象通常被称为“相位检测坏点”。坏点可能由多种原因引起,包括物理损伤、制造缺陷或长期使用后的老化等问题[^1]。 #### 坏点的表现形式 在实际应用中,相位检测坏点可能导致以下几种情况: - 对焦点无法正常工作或者表现出明显的延迟。 - 部分区域内的物体难以实现快速精准对焦。 - 图像质量受到影响,在某些情况下可能出现模糊或其他光学异常[^3]。 #### 修复方法分析 针对上述提到的各种表现形式以及潜在成因,可以采取如下措施来进行诊断与维修: ##### 软件校正 一些轻微损坏可以通过软件手段加以补偿。现代数码设备往往内置有自动修正算法能够识别并标记那些已知存在问题的位置,并通过插值法填补缺失数据从而改善整体效果。这种方法虽然不能彻底恢复受损硬件的功能,但在一定程度上仍可维持较好的用户体验[^2]。 ```python def pdaf_correction(image_data, bad_pixel_map): corrected_image = [] height, width = image_data.shape for y in range(height): row_corrected = [] for x in range(width): if (x,y) in bad_pixel_map: # 使用周围有效像素平均值代替坏点 avg_value = calculate_average_neighbor(image_data, x, y) row_corrected.append(avg_value) else: row_corrected.append(image_data[y][x]) corrected_image.append(row_corrected) return np.array(corrected_image) ``` ##### 硬件更换/修理 对于较为严重的损害,则需考虑更深入的技术干预比如替换整个感光元件或是单独修复有问题的部分电路板组件等操作。这一步骤一般需要交由专业技术人员执行以确保不会进一步破坏其他完好部件[^4]。 #### 总结 综上所述,处理相位检测中的坏点问题可以从软硬两个方面入手。前者适用于初期阶段的小范围影响;而后者则是面对较大规模结构性毁损时更为可靠的选择。无论采用哪种方式都建议事先做好充分准备并与经验丰富的专家沟通交流以便获得最佳解决方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值