当前位置:   article > 正文

顶象面积点选验证码----Python破解代码_顶象文字点选逆向

顶象文字点选逆向

可解顶象的面积点选验证码

在线测试地址:simple_ocr

在这里插入图片描述
在同级目录下保存一张名为1.png的面积点选验证码图片,运行代码即可获得最大面积的像素坐标。
不罗嗦,直接给代码

'''
面积点选验证码

'''

'''
面积点选验证码

'''


import copy

from PIL import Image
import numpy as np
import cv2



class Acreage():




    #寻找最大连通域算法
    def select_max_region(self,mask):
        nums, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, connectivity=8)
        background = 0
        for row in range(stats.shape[0]):
            if stats[row, :][0] == 0 and stats[row, :][1] == 0:
                background = row
        stats_no_bg = np.delete(stats, background, axis=0)
        max_idx = stats_no_bg[:, 4].argmax()
        max_region = np.where(labels==max_idx+1, 1, 0)

        return max_region

    #加粗算法
    def expansion_px(self,img_arrays,n,h,w):
        for i in range(-n,n+1):
            for j in range(-n,n+1):
                try:
                    img_arrays[h + i, w+j] = (255, 255, 255)
                except:
                    continue
        return img_arrays

    #二值化
    def binaryzation(self,n=155):
        input_img_file= '1.png'
        gray = cv2.imread(input_img_file)

        # 固定阈值设置
        ret, binary = cv2.threshold(gray, n, 255, cv2.THRESH_BINARY)
        cv2.imwrite('1.png',binary)


    #灰度
    def gray(self,):
        image = cv2.imread("1.png")
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        cv2.imwrite('1.png', gray)


    #加粗分割线,使其形成多个独立的区域
    def zoning(self,n=7):

        '''

        :param n: 加粗像素大小,默认为7,小了没效果,大了太慢
        :return:
        '''

        img = Image.open("1.png")

        img_array = np.array(img)  # 把图像转成数组格式img = np.asarray(image)
        img_arrays = copy.deepcopy(img_array)
        shape = img_array.shape

        height = shape[0]
        width = shape[1]
        dst = np.zeros((height, width, 3))
        for h in range(0, height):
            for w in range(0, width):
                (b, g, r) = img_array[h, w]

                if b == 255 and g ==255  and r==255:

                    for i in range(1,n+1):
                        img_arrays = self.expansion_px(img_arrays,i,h,w)




                dst[h, w] = img_arrays[h, w]
        img2 = Image.fromarray(np.uint8(dst))
        img2.save("1.png", "png")

    #选出最大面积
    def  max_area(self,):
        img = cv2.imread('1.png')
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
        mask = self.select_max_region(mask)

        cv2.imwrite('1.png', mask * 255)


    #给出点击坐标
    def x_y_xp(self,):
        import cv2

        img = cv2.imread("1.png")
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        ret, thresh = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
        contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

        for i in range(len(contours)):
            x, y, w, h = cv2.boundingRect(contours[i])
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 1)
            rect = cv2.minAreaRect(contours[i])
            cv2.circle(img, (int(rect[0][0]), int(rect[0][1])), 2, (0, 0, 255), 2)
            return int(rect[0][0]), int(rect[0][1])


    #反转颜色
    def negative(self,):
        img = cv2.imread('1.png', 1)
        img_shape = img.shape  # 图像大小(565, 650, 3)
        # 彩色图像转换为灰度图像(3通道变为1通道)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        # 最大图像灰度值减去原图像,即可得到反转的图像
        dst = 255 - gray

        cv2.imwrite('1.png', dst)


    #去噪点
    def degrains(self,):

        def clamp(pv):
            if pv > 255:
                return 255
            if pv < 0:
                return 0
            else:
                return pv

        def gaussian_noise(image):  # 加高斯噪声
            h, w, c = image.shape
            for row in range(h):
                for col in range(w):
                    s = np.random.normal(0, 20, 3)
                    b = image[row, col, 0]  # blue
                    g = image[row, col, 1]  # green
                    r = image[row, col, 2]  # red
                    image[row, col, 0] = clamp(b + s[0])
                    image[row, col, 1] = clamp(g + s[1])
                    image[row, col, 2] = clamp(r + s[2])

        src = cv2.imread('1.png')


        gaussian_noise(src)
        dst = cv2.GaussianBlur(src, (15, 15), 0)  # 高斯模糊
        cv2.imwrite('1.png', dst)


    def degrain(self):

        def salt(img, n):
            for k in range(n):
                i = int(np.random.random() * img.shape[1])
                j = int(np.random.random() * img.shape[0])
                if img.ndim == 2:
                    img[j, i] = 255
                elif img.ndim == 3:
                    img[j, i, 0] = 255
                    img[j, i, 1] = 255
                    img[j, i, 2] = 255
                return img

        img = cv2.imread("./1.png", cv2.IMREAD_GRAYSCALE)
        result = salt(img, 500)
        median = cv2.medianBlur(result, 5)
        cv2.imwrite('1.png', median)

    def mains(self,):
        self.gray()
        self.binaryzation()
        self.zoning()
        self.degrain()
        self.max_area()

        self.negative()
        self.max_area()
        data = self.x_y_xp()
        return data
        # return  1

if __name__ == '__main__':
    a = Acreage()
    data = a.mains()
    print(data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205

思路借鉴:100%成功率的顶象面积验证码识别方案

原理:
1、首先对验证码图片转灰度二值化
灰度:
在这里插入图片描述
二值:阈值我给的是155,实际使用你们看着改就可以

在这里插入图片描述

2、加粗白色像素(也就相当于加粗分割线了)

在这里插入图片描述

3、 保留最大连通域(白色认作连通域)
在这里插入图片描述

4、反转颜色(这一步完全是我懒所以加的,其实可以改改去掉这一步的)

在这里插入图片描述

5、寻找最大连通域
在这里插入图片描述

6、找出连通域最小外接矩形,然后取中心点的定位(这里其实有一个隐患,有可能点的位置并没有在在连通域上,要求高的可以自己改下)
在这里插入图片描述

————————以下是笔者的碎碎念————————————

打算出一个系列,把市面上所有验证码做一个破解,下一个准备做贴吧的旋转验证码,就是这种
在这里插入图片描述
如果大家有什么想要解决的验证码,可以在评论区留言下,我会优先做你们评论的验证码的。
另外该代码可能有bug啥的或者有其他更好的方法

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/527696
推荐阅读
相关标签
  

闽ICP备14008679号