Ejemplo n.º 1
0
 def _ehead(self, data: bytes):
     header = b'FsTeg\x01\x02\x03'
     ee = pad(data, self.block_size)
     ll = struct.pack('i', 1 + len(ee) // self.block_size)
     _rrs1 = RSCodec()
     _rrs2 = RSCodec(_check)
     return _rrs1.encode(pad(header + ll, _header_size - 10)) + _rrs2.encode(pad(data, _rsc_block))
Ejemplo n.º 2
0
def reed_solomon_encode(txt: typing.Union[bytes, str, bytearray],
                        number_repair_symbols: int = 2) -> bytes:
    global rscodec, number_r_symbols
    if rscodec is None or number_r_symbols != number_repair_symbols:
        rscodec = RSCodec(number_repair_symbols)
        number_r_symbols = number_repair_symbols
    return bytes(rscodec.encode(txt))
Ejemplo n.º 3
0
 def test_prim_fcr_basic(self):
     nn = 30
     kk = 18
     tt = nn - kk
     rs = RSCodec(tt, fcr=120, prim=0x187)
     hexencmsg = '00faa123555555c000000354064432c02800fe97c434e1ff5365' \
         'cf8fafe4'
     strf = str if sys.version_info[0] >= 3 else unicode    
     encmsg = bytearray.fromhex(strf(hexencmsg))
     decmsg = encmsg[:kk]
     tem = rs.encode(decmsg)
     self.assertEqual(encmsg, tem, msg="encoded does not match expected")
     tdm = rs.decode(tem)
     self.assertEqual(tdm, decmsg, msg="decoded does not match original")
     tem1 = bytearray(tem) # clone a copy
     # encoding and decoding intact message seem OK, so test errors
     numerrs = tt >> 1 # inject tt/2 errors (expected to recover fully)
     for i in sample(range(nn), numerrs): # inject errors in random places
         tem1[i] ^= 0xff # flip all 8 bits
     tdm = rs.decode(tem1)
     self.assertEqual(tdm, decmsg,
         msg="decoded with errors does not match original")
     tem1 = bytearray(tem) # clone another copy
     numerrs += 1 # inject tt/2 + 1 errors (expected to fail and detect it)
     for i in sample(range(nn), numerrs): # inject errors in random places
         tem1[i] ^= 0xff # flip all 8 bits
     # if this fails, it means excessive errors not detected
     self.assertRaises(ReedSolomonError, rs.decode, tem1)
Ejemplo n.º 4
0
class TMEncoder:
    def __init__(self):
        self.rsc = RSCodec(ECC)

    def encode_tc_datalink_packets(self, datalink_packets) -> bytes:
        bytestream = b''
        for packet in datalink_packets:
            bytestream += self.encode_bytes(packet.to_bytes())
        return bytestream

    def encode_bytes(self, data):
        frames = []
        for i in range(0, len(data), FRAME_LENGTH):
            frame = data[i:i + FRAME_LENGTH]
            encoded_data = self.rsc.encode(frame)
            sync_frame = ASM + encoded_data
            frames.append(sync_frame)
        return b''.join(frames)

    def convolve_code(self, data):
        bits = bytes_2_bits(data)
        state = collections.deque([0, 0, 0, 0, 0, 0], 6)
        c_bits = []
        for bit in bits:
            c1 = bit ^ state[0] ^ state[1] ^ state[2] ^ state[5]
            c2 = bit ^ state[1] ^ state[2] ^ state[4] ^ state[5]
            state.appendleft(bit)
            c_bits.append(c1)
            c_bits.append(abs(c2 - 1))
        return bits_2_bytes(c_bits)
Ejemplo n.º 5
0
 def test_prim_fcr_long(self):
     nn = 48
     kk = 34
     tt = nn - kk
     rs = RSCodec(tt, fcr=120, prim=0x187)
     hexencmsg = '08faa123555555c000000354064432c0280e1b4d090cfc04887400' \
         '000003500000000e1985ff9c6b33066ca9f43d12e8'
     strf = str if sys.version_info[0] >= 3 else unicode    
     encmsg = bytearray.fromhex(strf(hexencmsg))
     decmsg = encmsg[:kk]
     tem = rs.encode(decmsg)
     self.assertEqual(encmsg, tem, msg="encoded does not match expected")
     tdm = rs.decode(tem)
     self.assertEqual(tdm, decmsg, 
         msg="decoded does not match original")
     tem1 = bytearray(tem)
     numerrs = tt >> 1
     for i in sample(range(nn), numerrs):
         tem1[i] ^= 0xff
     tdm = rs.decode(tem1)
     self.assertEqual(tdm, decmsg,
         msg="decoded with errors does not match original")
     tem1 = bytearray(tem)
     numerrs += 1
     for i in sample(range(nn), numerrs):
         tem1[i] ^= 0xff
     self.assertRaises(ReedSolomonError, rs.decode, tem1)
Ejemplo n.º 6
0
def generate(n, k=12, mnemonic=Mnemonic("english")):
    """Generate a mnemonic phrase with the specified level of error correction.

    Phrases include t=(n-k) "error correcting" words, allowing the correction of up to t invalid
    words in a phrase, and up to floor(t/2) words that are wrong, but still valid BIP-39 words.

    Arguments:
        n (int): Total number of words in the phrase.
        k (int): Number of words chosen at random.
        mnemonic (Mnemonic): Instance of Mnemonic to use.
    """
    ok, error = validate_n_k(n, k)
    if not ok:
        raise ValueError(error)

    coder = RSCodec(nsize=n, nsym=(n-k), c_exp=BIP39_SYMBOL_SIZE)
    for i in itertools.count():
        bits = random_bits(k*BIP39_SYMBOL_SIZE)
        symbols = bits_to_symbols(bits, BIP39_SYMBOL_SIZE)
        coded = coder.encode(symbols)
        phrase = symbols_to_mnemonic(coded, mnemonic)
        if not mnemonic.check(phrase):
            continue

        return phrase
Ejemplo n.º 7
0
def recover(phrase, k=12, mnemonic=Mnemonic("english")):
    """Attempts to recover the original mnemonic phrase from a mnemonic phrase with errors.

    Infers the value of n from the number of words in the phrase. If words are missing or unknown,
    include an arbitrary character in its place. (e.g. '_')

    Arguments:
        phrase (str): Mnemonic phrase with errors to fix.
        k (int): Number of words chosen at random.
        mnemonic (Mnemonic): Instance of Mnemonic to use.
    """
    symbols = mnemonic_to_symbols(phrase, mnemonic)
    ok, error = validate_n_k(len(symbols), k)
    if not ok:
        raise ValueError(error)

    coder = RSCodec(nsize=len(symbols), nsym=(len(symbols)-k), c_exp=BIP39_SYMBOL_SIZE)
    erasures = [i for i, s in enumerate(symbols) if s < 0]
    recovered, _, _ = coder.decode(symbols, erase_pos=erasures)
    coded = coder.encode(recovered)
    phrase = symbols_to_mnemonic(coded, mnemonic)

    if not mnemonic.check(phrase):
        raise ValueError("error-corrected phrase does not have a valid checksum")

    return phrase
Ejemplo n.º 8
0
def encodeWithReedSolo(bytedata, length=0):
    if len(bytedata) > 182 or length > 256:
        return b''
    ecc_len = 0
    if length == 0:
        # if len(bytedata) > 182:
        #     c = math.ceil(len(bytedata) / 2)
        #     if c > 182:
        #         c = 182
        #     return encodeWithReedSolo(bytedata[:c]) + encodeWithReedSolo(bytedata[c:])
        ecc_len = math.ceil(len(bytedata) * errorPercent)
    else:
        # if length > 255:
        #     c = math.ceil(length / 2)
        #     print(c)
        #     if c > 255:
        #         c = 255
        #     return encodeWithReedSolo(bytedata[:c]) + encodeWithReedSolo(bytedata[c:])
        print('use length ' + str(length))
        ecc_len = math.ceil(int(length) / (1 + errorPercent) * errorPercent)
        bytedata += os.urandom(math.floor(length - ecc_len - len(bytedata)))
    print('error: ' + str(ecc_len))
    print('random: ' + str(math.floor(length - ecc_len - len(bytedata))))
    print('data: ' + str(len(bytedata)))
    rsc = RSCodec(ecc_len)
    encodedata = rsc.encode(bytedata)
    print('ENCODED')
    print(len(encodedata))
    return encodedata
Ejemplo n.º 9
0
class CCSDS_Chunk_Packet(CCSDS_Packet):
    def __init__(self, packet_seq_num, telemetry_packet_type,
                 current_batch_num, current_chunk_num, chunk):
        self.rsc = RSCodec(16)  # 16 ecc symbols
        self.chunk = chunk
        packet_data = self._create_chunk_packet_data(telemetry_packet_type,
                                                     current_batch_num,
                                                     current_chunk_num, chunk)
        super().__init__(packet_seq_num, packet_data)

    def __str__(self):
        return f"chunk|seqnum:{self.packet_seq_num}|len:{len(self.get_tx_packet())}"

    def get_tx_packet(self):
        return self.header + self.packet_data

    def _create_chunk_packet_data(self, telemetry_packet_type,
                                  current_batch_num, current_chunk_num, chunk):
        TELEMETRY_TYPE_LENGTH = 1
        CURRENT_CHUNKS_LENGTH = 3  # bytes
        CURRENT_BATCH_LENGTH = 3

        data = bytearray(0)
        data = telemetry_packet_type.to_bytes(TELEMETRY_TYPE_LENGTH, 'big')
        data = data + current_batch_num.to_bytes(CURRENT_BATCH_LENGTH, 'big')
        data = data + current_chunk_num.to_bytes(CURRENT_CHUNKS_LENGTH, 'big')

        data += self.rsc.encode(chunk)

        return data
def listen_linux(frame_rate=44100, interval=0.1):

    mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE,
                        alsaaudio.PCM_NORMAL,
                        device="default")
    mic.setchannels(1)
    mic.setrate(44100)
    mic.setformat(alsaaudio.PCM_FORMAT_S16_LE)

    num_frames = int(round((interval / 2) * frame_rate))
    mic.setperiodsize(num_frames)
    print("start...")

    in_packet = False
    packet = []

    while True:
        l, data = mic.read()
        if not l:
            continue

        chunk = np.fromstring(data, dtype=np.int16)
        dom = dominant(frame_rate, chunk)
        #print(dom)

        if in_packet and match(dom, HANDSHAKE_END_HZ):
            byte_stream = extract_packet(packet)
            try:
                byte_stream = RSCodec(FEC_BYTES).decode(byte_stream)
                byte_stream = byte_stream.decode("utf-8")
                #print(byte_stream) #이 부분을 찍어보면 최종 문자열을 확인가능

                if "201502127" in byte_stream:  # in 키워드를 이용하면 문자열이 있는지를 찾을 수 있다.
                    ID_count = byte_stream.count(
                        "201502127")  #201502127이 몇번 출현하는지 찾는다.
                    byte_stream = extract_Data(byte_stream, ID_count)
                    display(byte_stream)

                    try:
                        byte_stream = RSCodec(FEC_BYTES).encode(
                            byte_stream.encode("utf-8")
                        )  # 필요한 데이터 뒤에 오류 코드까지 아스키 코드(1byte)로 인코딩 되어 나온다.
                        #print(byte_stream[0:4]) #byteArray가 된 " hel"이 출력됨.
                        sound(bytes_to_freq(byte_stream))

                    except ReedSolomonError as e:
                        pass
                        #print("{}: {}".format(e, byte_stream))

            except ReedSolomonError as e:
                pass
                #print("{}: {}".format(e, byte_stream))

            packet = []
            in_packet = False
        elif in_packet:
            packet.append(dom)
        elif match(dom, HANDSHAKE_START_HZ):
            in_packet = True
Ejemplo n.º 11
0
def main():

    for i in range(0, 256):
        postit = np.tile(np.uint8([255]), (postit_height, postit_width, 1))

        #draw location dot
        for count in range(0, 8):
            location_dot_array = [1] + [
                0 for j in range(0, location_dot_num - 1)
            ]
            for j in range(0, len(location_dot_array) - 2):
                if count & 2**j != 0:
                    location_dot_array[j + 1] = 1
            if count < 3:
                draw_location_dot(postit, location_dot_array,
                                  horizon_x_buffer + count * horizon_space,
                                  horizon_y_buffer, True)
            elif count < 6:
                draw_location_dot(
                    postit, location_dot_array,
                    horizon_x_buffer + (count - 3) * horizon_space,
                    postit_height - horizon_y_buffer - location_height, True)
            elif count == 6:
                draw_location_dot(postit, location_dot_array, horizon_y_buffer,
                                  postit_height / 2 - location_width / 2,
                                  False)
            elif count == 7:
                draw_location_dot(
                    postit, location_dot_array,
                    postit_width - horizon_y_buffer - location_height,
                    postit_height / 2 - location_width / 2, False)

        #need reed solomon
        rs = RSCodec(14)
        rs_result = rs.encode([i])

        #make bit array
        bit_array_all = []
        for number in rs_result:
            #print number
            bit_array = [0 for j in range(0, bit_num)]
            for j in range(0, bit_num - 1):
                if number & 2**j != 0:
                    bit_array[j] = 1
            bit_array[bit_num - 1] = bit_array[0]
            bit_array_all.append(bit_array)

        #draw bit array
        draw_all_bit(bit_array_all, postit)

        #outer rectangle
        cv2.rectangle(postit, (0, 0), (postit_width - 1, postit_height - 1), 0,
                      1)

        #cv2.imshow("result", postit)
        #cv2.waitKey(0)
        filename = "./datas/postit/postit" + str(i) + ".jpg"
        cv2.imwrite(filename, postit)
Ejemplo n.º 12
0
def encode(string, coding):
    #encode the text in bytes
    in_bytes = string.encode("utf-8")
    #compress the bytes
    compressed = zlib.compress(in_bytes, 9)
    # if coding!=0, add error correcting code
    if(coding):
        rs = RSCodec(coding)
        compressed = rs.encode(compressed)
    return compressed
Ejemplo n.º 13
0
 def test_long(self):
     rs = RSCodec(10)
     msg = bytearray("a" * 10000, "utf8")
     enc = rs.encode(msg)
     dec = rs.decode(enc)
     self.assertEqual(dec, msg)
     enc[177] = 99
     enc[2212] = 88
     dec2 = rs.decode(enc)
     self.assertEqual(dec2, msg)
Ejemplo n.º 14
0
 def test_correction(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "utf8")
     enc = rs.encode(msg)
     self.assertEqual(rs.decode(enc), msg)
     for i in [27, -3, -9, 7, 0]:
         enc[i] = 99
         self.assertEqual(rs.decode(enc), msg)
     enc[82] = 99
     self.assertRaises(ReedSolomonError, rs.decode, enc)
Ejemplo n.º 15
0
 def test_long(self):
     rs = RSCodec(10)
     msg = bytearray("a" * 10000, "utf8")
     enc = rs.encode(msg)
     dec = rs.decode(enc)
     self.assertEqual(dec, msg)
     enc[177] = 99
     enc[2212] = 88
     dec2 = rs.decode(enc)
     self.assertEqual(dec2, msg)
Ejemplo n.º 16
0
 def test_correction(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "utf8")
     enc = rs.encode(msg)
     self.assertEqual(rs.decode(enc), msg)
     for i in [27, -3, -9, 7, 0]:
         enc[i] = 99
         self.assertEqual(rs.decode(enc), msg)
     enc[82] = 99
     self.assertRaises(ReedSolomonError, rs.decode, enc)
Ejemplo n.º 17
0
def listen_linux(frame_rate=44100, interval=0.1):

    mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE,
                        alsaaudio.PCM_NORMAL,
                        device="default")
    mic.setchannels(1)
    mic.setrate(44100)
    mic.setformat(alsaaudio.PCM_FORMAT_S16_LE)

    num_frames = int(round((interval / 2) * frame_rate))
    mic.setperiodsize(num_frames)
    print("start...")

    in_packet = False
    packet = []

    while True:
        l, data = mic.read()
        if not l:
            continue

        chunk = np.fromstring(data, dtype=np.int16)
        dom = dominant(frame_rate,
                       chunk)  #소리를 주파수로 변환하는 함수(dominant), 소리에 맞게 주파수를 분리

        if in_packet and match(dom, HANDSHAKE_END_HZ):  #끝 주파수를 수신함
            byte_stream = extract_packet(
                packet)  #주파수의 묶음을 데이터로 바꿔줌(extract packet)
            try:
                byte_stream = RSCodec(FEC_BYTES).decode(
                    byte_stream)  #RSCodec 함수로 FEC_BYTES 디코딩
                byte_stream = byte_stream.decode("utf-8")  #문자값으로로 디코딩
                #print(byte_stream)

                if byte_stream[:9] == number:  #학번이 입력되면
                    #print(byte_stream[:9])
                    display(byte_stream[9:])  #학번 이후부터 결과출력

                    byte_stream = byte_stream[9:]
                    # print(byte_stream[9:])
                    byte_stream = byte_stream.encode("utf-8")  #아스키코드값으로 인코딩
                    byte_stream = RSCodec(FEC_BYTES).encode(
                        byte_stream)  #RSCodec 함수로 FEC_BYTES 인코딩
                    make_sound(byte_stream)  #make_sound함수 호출

            except ReedSolomonError as e:
                pass
                #print("{}: {}".format(e, byte_stream))

            packet = []
            in_packet = False
        elif in_packet:
            packet.append(dom)  #주파수를 받음
        elif match(dom, HANDSHAKE_START_HZ):
            in_packet = True
Ejemplo n.º 18
0
class RSCode:
    """ Reed-Solomon encoder and decoder """
    def __init__(self, num_ec=None):
        """ Create R.S. Code with given number of EC symbols. corrects num_ec / 2 errors. """
        self.num_ec = num_ec or config.RS_NUM_EC
        self.coder = RSCodec(self.num_ec)

    def encode(self, bitarr):
        output = []
        bitarr_bytes = _bitarr2bytes(bitarr, 8, 8)
        encoded = self.coder.encode(bitarr_bytes)
        output = _bytes2bitarr(encoded)
        return output

    def decode(self, bitarr, starts_to_try=10):
        if not bitarr:
            print('warning: empty block received')
            return
        # sometimes we have extra bytes at the beginning, fix that by bruteforcing
        for offs in range(starts_to_try):
            try:
                if len(bitarr) % 8:
                    # cut off unaligned
                    bitarr_trim = bitarr[:-len(bitarr) % 8]
                else:
                    bitarr_trim = bitarr

                if config.DEBUG:
                    import os.path
                    decoded = bitarr_trim[:]
                    if os.path.exists('_actual_message.npy'):
                        if offs:
                            print('reed-solomon offset =', offs)
                        actual = np.load('_actual_message.npy')
                        while len(decoded) > len(actual):
                            decoded.pop()
                        while len(decoded) < len(actual):
                            decoded.append(0)
                        Y = np.array(decoded)
                        X = np.array(actual)
                        bitwise_errs = np.sum(np.abs(Y - X))
                        X = X.reshape(-1, 8)
                        Y = Y.reshape(-1, 8)
                        errs = np.sum(np.any(X != Y, axis=1))
                        #print(X)
                        #print(Y)
                        print('bit errors', bitwise_errs, '=', bitwise_errs / len(decoded))
                        print('byte errors', errs, '=', errs / (len(decoded) // 8))
                bitarr_bytes = _bitarr2bytes(bitarr_trim, None)
                decoded = self.coder.decode(bitarr_bytes)[0]
                output = _bytes2bitarr(decoded)
                return _unpad(output, 8)
            except:
                bitarr = bitarr[8:]
        raise Exception('FATAL: reed-solomon decoding failed')
def listen_linux(frame_rate=44100, interval=0.1):

    mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL)
    mic.setchannels(1)
    mic.setrate(44100)
    mic.setformat(alsaaudio.PCM_FORMAT_S16_LE)

    num_frames = int(round((interval / 2) * frame_rate))
    mic.setperiodsize(num_frames)
    print("start...")

    in_packet = False
    packet = []

    while True:
        l, data = mic.read()
        if not l:
            continue

        chunk = np.fromstring(data, dtype=np.int16)
        dom = dominant(frame_rate, chunk)

        if in_packet and match(dom, HANDSHAKE_END_HZ):
            byte_stream = extract_packet(packet)
            print("original code", byte_stream)
            if match_num(byte_stream) == False:
                break

            try:
                byte_stream = RSCodec(FEC_BYTES).decode(byte_stream)
                byte_stream = byte_stream.decode("utf-8")
                print(byte_stream)
                byte_stream = byte_stream.replace("201702087", "")
                display(byte_stream)
                display("")

                sin_freq = []

                byte_stream = byte_stream.encode("utf-8")
                byte_stream = RSCodec(FEC_BYTES).encode(byte_stream)

                sin_freq = make_freq(byte_stream, sin_freq)
                print(sin_freq)
                make_sound(sin_freq)

            except ReedSolomonError as e:
                print("{}: {}".format(e, byte_stream))

            packet = []
            in_packet = False

        elif in_packet:
            packet.append(dom)
        elif match(dom, HANDSHAKE_START_HZ):
            in_packet = True
Ejemplo n.º 20
0
class PublicCode:
    def __init__(self):
        self.n = 78 * 768
        self.inner_code = RSCodec(78 - 32)
        self.outer_code = ReedMuller(6)

    def encode(self, msg):
        return self.outer_code.encode(self.inner_code.encode(msg))

    def decode(self, msg):
        return self.inner_code.decode(self.outer_code.decode(msg))
Ejemplo n.º 21
0
    def _genErrorCorrection(self, codewords):
        """ Turn codewords into error-corrected data groups """
        # Get EC info
        block_info = QRCode.BLOCK_LIST[self.version - 1][self.ecc]

        # Split into groups of blocks
        groups = ([], [])
        first_block_size = block_info[2]
        for block in range(block_info[1]):
            groups[0].append(codewords[first_block_size *
                                       block:first_block_size * (block + 1)])

        # Same for second group
        if len(
                block_info
        ) == 5:  # There will be 5 elements in the info tuple if there are 2 groups
            offset = first_block_size * block_info[1]
            second_block_size = block_info[4]
            for block in range(block_info[3]):
                groups[1].append(
                    codewords[offset + second_block_size * block:offset +
                              second_block_size * (block + 1)])

        # Do first group's error correction
        ec_groups = ([], [])
        ecc_codewords = block_info[0]
        rscodec = RSCodec(ecc_codewords)
        for b in range(len(groups[0])):
            # Get full error corrected (EC) codewords as bytes and extract only EC bytes
            ecBytes = rscodec.encode(groups[0][b])[block_info[2]:]
            # Append to list of EC codewords
            ec_groups[0].append(ecBytes)

        # Do second group's error correction
        if len(block_info) == 5:
            for b in range(len(groups[1])):
                # Same thing as for first group
                ecBytes = rscodec.encode(groups[1][b])[block_info[4]:]
                ec_groups[1].append(ecBytes)

        return groups, ec_groups
Ejemplo n.º 22
0
class Sender:
    def __init__(self, msg, encode_method, bits_per_packet):
        self.msg = msg
        self.encode_method = encode_method
        self.bits_per_packet = bits_per_packet
        self.counter = 0
        self.rsc = RSCodec(SALOMON_DEPTH)

    def get_encoded_msg(self):
        while len(self.msg) >= (self.counter + 1) * self.bits_per_packet:
            if self.encode_method == TRIPLE:
                yield self._get_triple_packet()
            elif self.encode_method == HAMMING:
                yield self._get_hamming_packet()
            elif self.encode_method == SALOMON:
                yield self._get_salomon_packet()
            else:
                raise

    def _get_triple_packet(self):
        packet_start = self.counter * self.bits_per_packet
        packet_end = (self.counter + 1) * self.bits_per_packet
        packet = self.msg[packet_start:packet_end]
        encoded_packet = []

        for bit in packet:
            for i in range(MULTIPLIER):
                encoded_packet.append(bit)

        self.counter += 1
        return encoded_packet

    def _get_hamming_packet(self):
        packet_start = self.counter * self.bits_per_packet
        packet_end = (self.counter + 1) * self.bits_per_packet
        packet = self.msg[packet_start:packet_end]
        number = ImageBitParser.bit_array_to_number(packet)
        encoded_packet = [
            int(bit)
            for bit in hamming_codec.encode(number, self.bits_per_packet)
        ]
        self.counter += 1
        return encoded_packet

    def _get_salomon_packet(self):
        packet_start = self.counter * self.bits_per_packet
        packet_end = (self.counter + 1) * self.bits_per_packet
        packet = self.msg[packet_start:packet_end]
        encoded_value = self.rsc.encode(packet)
        for number in encoded_value[self.bits_per_packet:]:
            packet += ImageBitParser.number_to_bit_array(number, 8)
        self.counter += 1
        return packet
Ejemplo n.º 23
0
def trame(data, conf):
    out = bytearray([conf["trame"]["startbyte"]])

    for i, val in enumerate(data): # Concaténation des valeurs des capteurs
        out += struct.pack(str("!"+ conf["sensors"][i]), *val)

    out += bytearray([functools.reduce(operator.xor, out)])

    rs = RSCodec(conf["trame"]["ecc"]["length"])
    out = rs.encode(out)

    return out
Ejemplo n.º 24
0
def dna_reed_solomon_encode(txt: typing.Union[bytes, str, bytearray],
                            number_repair_symbols: int = 2,
                            c_exp: int = 2,
                            prim_poly: int = 7) -> bytes:
    """
    Warning: dna_reed_solomon_* requires a custom RSCodec version with support for custom c_exp and nsize.
    """
    tmp_rscodec = RSCodec(number_repair_symbols,
                          c_exp=c_exp,
                          prim=prim_poly,
                          nsize=2**c_exp - 1)
    dec_list = bits_to_dec(txt)
    return bytes(tmp_rscodec.encode(dec_list))
Ejemplo n.º 25
0
def listen_linux(frame_rate=44100, interval=0.1):

    mic = alsaaudio.PCM(alsaaudio.PCM_CAPTURE,
                        alsaaudio.PCM_NORMAL,
                        device="default")
    mic.setchannels(1)
    mic.setrate(44100)
    mic.setformat(alsaaudio.PCM_FORMAT_S16_LE)

    num_frames = int(round((interval / 2) * frame_rate))
    mic.setperiodsize(num_frames)
    print("start...")

    in_packet = False
    packet = []

    while True:
        l, data = mic.read()
        if not l:
            continue

        chunk = np.fromstring(data, dtype=np.int16)
        dom = dominant(frame_rate, chunk)

        if in_packet and match(dom, HANDSHAKE_END_HZ):
            byte_stream = extract_packet(packet)
            try:
                byte_stream = RSCodec(FEC_BYTES).decode(byte_stream)
                byte_stream = byte_stream.decode("utf-8")
                if ID in byte_stream:
                    global result_stream
                    #print(byte_stream)
                    result_stream = byte_stream.replace(ID, '')
                    result_stream = result_stream.strip()

                    rs = RSCodec(4)
                    result_stream = rs.encode(result_stream)
                    print(result_stream)
                    play_linux()

                display(byte_stream)
            except ReedSolomonError as e:
                pass
                #print("{}: {}".format(e, byte_stream))

            packet = []
            in_packet = False
        elif in_packet:
            packet.append(dom)
        elif match(dom, HANDSHAKE_START_HZ):
            in_packet = True
Ejemplo n.º 26
0
class ReedSolomon(AbstractErrorCorrectionCode):

    def __init__(self, check_size=3, need_logs=False):
        self.check_size = check_size
        self.tool = RSCodec(check_size)
        super().__init__(need_logs)

    def insert_one(self, input_list):
        if len(input_list) % 8 != 0:
            raise ValueError("The length of inputted binary segment must be divided by 8!")

        byte_list = []
        for index in range(0, len(input_list), 8):
            byte_list.append(int(str("".join(list(map(str, input_list[index: index + 8])))), 2))

        output_list = []
        for one_byte in list(self.tool.encode(byte_list)):
            temp_bits = list(map(int, list(bin(one_byte))[2:]))
            temp_bits = [0 for _ in range(8 - len(temp_bits))] + temp_bits
            output_list += temp_bits

        return output_list

    def remove_one(self, input_list):
        original_input_list = copy.deepcopy(input_list)

        byte_list = []
        for index in range(0, len(input_list), 8):
            byte_list.append(int(str("".join(list(map(str, input_list[index: index + 8])))), 2))

        try:
            decode_byte_list = list(self.tool.decode(byte_list))
            # fix error in Linux or Mac OS, TypeError: 'bytearray' object cannot be interpreted as an integer
            if type(decode_byte_list[0]) is not int:
                decode_byte_list = list(decode_byte_list[0])

            output_list = []
            for one_byte in list(decode_byte_list):
                temp_bits = list(map(int, list(bin(one_byte))[2:]))
                temp_bits = [0 for _ in range(8 - len(temp_bits))] + temp_bits
                output_list += temp_bits
        except ReedSolomonError:
            # Irreparable
            return {"data": original_input_list, "type": False}
        except IndexError:
            # No data acquisition
            return {"data": original_input_list, "type": False}

        return {"data": output_list, "type": True}
Ejemplo n.º 27
0
def rsencode(msg):
    '''
    msg: 二进制流
    '''
    # msg = '00110001001100100011001100110100001101010011011000110111'
    # return msg
    while len(msg) % 7:
        msg += '0'
    temp = ''
    for i in range(0, len(msg), 7):
        temp += chr(int(msg[i:i + 7], 2))
    ecc = RSCodec(96)
    byte_msg = ecc.encode(temp)
    rscode = byte_msg[len(temp):]
    binary_code = ''.join(format(x, '08b') for x in rscode)
    return msg + binary_code
Ejemplo n.º 28
0
def distrupt_message(message):
    """Distrupt a given message."""
    length = len(message)
    rsc = RSCodec(length)
    b = bytearray()
    b.extend(map(ord, message))
    b_arr = rsc.encode(b)
    disrupted_arr = bytearray()
    count = 0
    for a in b_arr:
        if count < length and count % 3 == 0:
            a = 88
        disrupted_arr.append(a)
        count += 1
    disrupted_string = disrupted_arr[0:length].decode("utf-8")
    return (disrupted_string, disrupted_arr, length)
Ejemplo n.º 29
0
Archivo: rss.py Proyecto: sz3/cimbar
class reed_solomon_stream:
    def __init__(self, f, ec=30, chunk_size=155, mode='read', on_failure=None):
        if mode not in ['read', 'write']:
            raise Exception('bad bit_file mode. Try "read" or "write"')
        self.mode = mode
        self.rsc = RSCodec(ec, nsize=chunk_size, fcr=1, prim=0x187)
        self.chunk_size = chunk_size
        self.empty_chunk = b'\0' * (chunk_size -
                                    ec) if on_failure is None else on_failure

        if isinstance(f, str):
            fmode = 'wb' if mode == 'write' else 'rb'
            self.f = open(f, fmode)
        else:
            self.f = f

    @property
    def closed(self):
        return self.f.closed

    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        if not self.f.closed:
            with self.f:  # close file
                pass

    def write(self, buffer):
        i = 0
        while i < len(buffer):
            bu = buffer[i:i + self.chunk_size]
            try:
                decoded = bytes(self.rsc.decode(bu)[0])
                self.f.write(decoded)
            except:
                print(f'failed decode at {i}')
                self.f.write(self.empty_chunk)
            i += self.chunk_size

    def read(self, max_bytes):
        raw = self.f.read(max_bytes)
        return self.rsc.encode(raw)
Ejemplo n.º 30
0
def generateWave(data):
    deleteOldWavs()

    recordStartChar()

    rs = RSCodec(10)

    dataHex = data.encode("ascii")
    dataHex = rs.encode(dataHex)
    dataHex = hexlify(dataHex)

    index = 1
    for c in dataHex:
        if index is ((len(data)+1)*2):
            recordSineWave(index, DELIMITER_FREQUENCY, DATA_PERIOD_MS)
            index = index + 1

        recordSineWave(index, NOTES[c], DATA_PERIOD_MS)
        index = index + 1

    recordStopChar(index)
    combineWavs(index+1)
Ejemplo n.º 31
0
def code(data):
    data = bytes(data, encoding='utf8')
    rsc = RSCodec(10)
    coded_data = rsc.encode(data)
    binary_coded_data = ''
    for byte in coded_data:
        binary = bin(byte)[2::]
        binary = '0' * (8 - len(binary)) + binary
        binary_coded_data += binary
    quart_coded_data = '0123'
    for i in range(0, len(binary_coded_data), 2):
        byte_pair = binary_coded_data[i] + binary_coded_data[i + 1]
        if byte_pair == '00':
            quart_coded_data += '0'
        elif byte_pair == '01':
            quart_coded_data += '1'
        elif byte_pair == '10':
            quart_coded_data += '2'
        elif byte_pair == '11':
            quart_coded_data += '3'
        else:
            raise ValueError
    quart_coded_data += '3333'
    return quart_coded_data
Ejemplo n.º 32
0
class Packetizer():
    def __init__(self, callsign):
        self.sequenceId = 0
        callsignLen = 6 if len(callsign) > 6 else len(callsign)
        self.callsign = bytes(
            callsign[:callsignLen].upper() + ' ' * (6 - len(callsign)),
            'utf-8')
        self.rs = RSCodec(16)

    def createPacket(self, data=b''):
        packet = bytearray()

        # Header (1 byte - added after padding)
        # Callsign (6 bytes)
        packet += self.callsign

        # Length (2 bytes)
        dataLen = len(data)
        packet += bytes([(dataLen & 0xFF00) >> 8, dataLen & 0xFF])

        # Sequence ID (2 bytes)
        packet += bytes([(self.sequenceId & 0xFF00) >> 8,
                         self.sequenceId & 0xFF])
        self.sequenceId = (self.sequenceId + 1) & 0xFFFF

        # payload (unknown length)
        packet += data

        # CRC and footer (CRC MSB, CRC LSB) (2 bytes)
        crcCalculator = CRC16()
        crc = crcCalculator.calculate(bytes(packet))
        packet += bytes([(crc & 0xFF00) >> 8, crc & 0xFF])

        cobs_packet = cobs.encode(packet)
        encoded_packet = self.rs.encode(cobs_packet)
        return bytes([0]) + encoded_packet + bytes([0])
Ejemplo n.º 33
0
class Watermarker(object):
    EPSILON = 0.001

    def __init__(self, max_payload, ec_bytes, seed=1910819922, mother="haar"):
        self.mother = mother
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8

        rand = Random(seed)
        chunk_size = 3000
        while True:
            self.seq0 = numpy.array(
                [int(rand.random() > 0.8) for _ in range(chunk_size)])
            self.seq1 = numpy.array(
                [int(rand.random() > 0.75) for _ in range(chunk_size)])
            corr, _ = pearsonr(self.seq0, self.seq1)
            if corr < self.EPSILON:
                break

    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        target = cD.reshape(cD.size)
        chunk_size = target.size // self.total_bits
        sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size])

        for i, bit in enumerate(iterbits(payload)):
            seq = sequence_of[bit]
            #chunk = target[i::self.total_bits][:seq.size]
            chunk = target[i * chunk_size:i * chunk_size + seq.size]
            chunk += k * seq
        return idwt2((cA, (cH, cV, target.reshape(cH.shape))),
                     self.mother)[:img.shape[0], :img.shape[1]]

    def embed(self, img, payload, k):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        payload = bytearray(payload) + "\x00" * (self.max_payload -
                                                 len(payload))
        encoded = self.rscodec.encode(payload)

        if len(img.shape) == 2:
            return self._embed(img, encoded, k)
        elif len(img.shape) == 3:
            output = numpy.zeros(img.shape)
            for i in range(img.shape[2]):
                output[:, :, i] = self._embed(img[:, :, i], encoded, k)
            return output
        else:
            raise TypeError("img must be a 2d or 3d array")

    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        target = cD.reshape(cD.size)
        chunk_size = target.size // self.total_bits
        seq0 = self.seq0[:chunk_size]
        seq1 = self.seq1[:chunk_size]

        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            chunk = target[i * chunk_size:(i * chunk_size) + seq0.size]
            #chunk = target[i::self.total_bits][:seq0.size]
            #if not all(chunk[i] == chunk[i+1] for i in range(chunk.size-1)):
            corr0, _ = pearsonr(chunk, seq0)
            corr1, _ = pearsonr(chunk, seq1)
            bit = int(corr1 > corr0)
            #else:
            #    bit = 0
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        print repr(output)
        return output

    def extract(self, img):
        if len(img.shape) == 2:
            return self.rscodec.decode(self._extract(img))
        elif len(img.shape) == 3:
            for i in range(img.shape[2]):
                try:
                    return self.rscodec.decode(self._extract(img[:, :, i]))
                except ReedSolomonError:
                    pass
            return self.rscodec.decode(self._extract(mean(img, 2)))
        else:
            raise TypeError("img must be a 2d or 3d array")
Ejemplo n.º 34
0
 def test_simple(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "utf8")
     enc = rs.encode(msg)
     dec = rs.decode(enc)
     self.assertEqual(dec, msg)
Ejemplo n.º 35
0
    def decode_rs(fragments):
        fragment_lengths = ", ".join(["{}:{}".format(i, len(f)) for i,f in enumerate(fragments)])
        p.pr("RS decode {} fragments of length {}".format(
            len(fragments), fragment_lengths))

        #for f in fragments:
        #    p.hexpr("  ZE FRAGMENT", f);

        # Transpose fragments to get an RS block
        rs_block = "".join("".join(f) for f in zip(*fragments))

        # chunks before protection have size chunk_size
        # protection adds 48 bytes
        # The tuples here are (data, parity)

        #p.hexpr("  ZE RS BLOCK", "".join(rs_block))

        num_chunks = len(rs_block) / chunk_size

        data_size = chunk_size + 48

        af_packet_size = num_chunks * chunk_size
        p.pr("AF Packet size {}".format(af_packet_size))

        # Cut the block into list of (data, protection) tuples
        rs_chunks = [ (rs_block[i*data_size:i*data_size + chunk_size],
                       rs_block[i*data_size + chunk_size:(i+1)*data_size])
                for i in range(num_chunks)]

        chunk_lengths = ", ".join(["{}:{}+{}".format(i, len(c[0]), len(c[1])) for i,c in enumerate(rs_chunks)])
        p.pr("{} chunks of length {}".format(num_chunks, chunk_lengths))

        #for c in rs_chunks:
        #    p.hexpr("  ZE CHUNK DATA", c[0]);
        #    p.hexpr("  ZE CHUNK PROT", c[1]);

        if verify_protection:
            rs_codec = RSCodec(48, fcr=1)

            protection_ok = True
            for chunk, protection in rs_chunks:
                #p.pr(" Protection")
                #p.hexpr("  OF ZE CHUNK DATA", chunk);

                bchunk = bytearray(chunk)
                padbytes = 255-(48 + len(chunk))
                bchunk = bchunk + bytearray(0 for i in range(padbytes))
                recalc_protection = rs_codec.encode(bchunk)[-48:]
                if protection != recalc_protection:
                    p.pr("  PROTECTION ERROR")
                    p.hexpr("  data", chunk)
                    p.hexpr("  orig", protection)
                    p.hexpr("  calc", recalc_protection)
                    protection_ok = False
                else:
                    p.pr("  PROTECTION OK")

            if protection_ok:
                p.pr("Protection check: OK")



        afpacket = "".join(data for (data, protection) in rs_chunks)

        #p.hexpr("  ZE AF PACKET", afpacket)

        if zeropad:
            return decode_af(afpacket[0:-zeropad])
        else:
            return decode_af(afpacket)
Ejemplo n.º 36
0
class Watermarker(object):
    def __init__(self, max_payload, ec_bytes, seed = 1895746671, mother = "bior3.1", sparsity = 0.7):
        self.mother = mother
        self.sparsity = sparsity
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8
        self.seed = seed
    
    '''
    def _interleave(self, cH, cV, cD):
        vec = numpy.zeros(cH.size + cV.size + cD.size)
        rcH = cH.ravel()
        lH = cH.size
        rcV = cV.ravel()
        lV = cH.size + cV.size
        rcD = cD.ravel()
        
        rand = Random(self.seed)
        indexes = range(vec.size)
        rand.shuffle(indexes)
        for i, j in enumerate(indexes):
            vec[i] = rcD[j - lV] if j >= lV else (rcV[j - lH] if j >= lH else rcH[j])
        return vec
    
    def _deinterleave(self, vec, cH, cV, cD):
        cH2 = numpy.zeros(cH.shape)
        rcH = cH2.ravel()
        lH = cH.size
        cV2 = numpy.zeros(cV.shape)
        rcV = cV2.ravel()
        lV = cH.size + cV.size
        cD2 = numpy.zeros(cD.shape)
        rcD = cD2.ravel()
        
        rand = Random(self.seed)
        indexes = range(vec.size)
        rand.shuffle(indexes)
        for i, v in enumerate(vec):
            j = indexes[i]
            if j >= lV:
                rcD[j -lV] = v
            elif j >= lH:
                rcV[j - lH] = v
            else:
                rcH[j] = v
        return cH2, cV2, cD2
    '''

    @classmethod
    def _interleave(cls, cH, cV, cD):
        vec = numpy.zeros(cH.size + cV.size + cD.size, dtype = float)
        vec[0::3] = cH.ravel()
        vec[1::3] = cV.ravel()
        vec[2::3] = cD.ravel()
        return vec
    
    @classmethod
    def _deinterleave(cls, vec, cH, cV, cD):
        return vec[0::3].reshape(cH.shape), vec[1::3].reshape(cV.shape), vec[2::3].reshape(cD.shape)
    
    def _generate_sequences(self, chunk_size):
        rand = Random(self.seed)
        seq0 = numpy.array([int(rand.random() >= self.sparsity) for _ in range(chunk_size)])
        seq1 = seq0[::-1]
        return seq0, seq1
    
    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother)
        vec = self._interleave(cH, cV, cD)
        chunk_size = vec.size // self.total_bits
        sequences = self._generate_sequences(chunk_size)
        
        for i, bit in enumerate(iterbits(payload)):
            offset = i * chunk_size
            vec[offset : offset + chunk_size] += k * sequences[bit]
            #vec[i:self.total_bits*chunk_size:self.total_bits] += k * sequences[bit]
        
        w, h = img.shape
        cH2, cV2, cD2 = self._deinterleave(vec, cH, cV, cD)
        return idwt2((cA, (cH2, cV2, cD2)), self.mother)[:w,:h]
    
    def embed(self, img, payload, k = 6, tv_denoising_weight = 4, rescale = True):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload))
        encoded = self.rscodec.encode(padded)
        
        if img.ndim == 2:
            output = self._embed(img, encoded, k)
        elif img.ndim == 3:
            output = numpy.zeros(img.shape, dtype=float)
            for i in range(img.shape[2]):
                output[:,:,i] = self._embed(img[:,:,i], encoded, k)
            #y, cb, cr = rgb_to_ycbcr(img)
            #y2 = self._embed(y, encoded, k)
            #cb = self._embed(cb, encoded, k)
            #cr = self._embed(cr, encoded, k)
            #y2 = rescale_intensity(y2, out_range = (numpy.min(y), numpy.max(y)))
            #Cb2 = rescale_intensity(Cb2, out_range = (numpy.min(Cb), numpy.max(Cb)))
            #Cr2 = rescale_intensity(Cr2, out_range = (numpy.min(Cr), numpy.max(Cr)))
            #output = ycbcr_to_rgb(y2, cb, cr)
        else:
            raise TypeError("img must be a 2d or 3d array")
        
        #if tv_denoising_weight > 0:
        #    output = tv_denoise(output, tv_denoising_weight)
        if rescale:
            output = rescale_intensity(output, out_range = (numpy.min(img), numpy.max(img)))
        #return toimage(output,cmin=0,cmax=255)
        return output
    
    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother)
        vec = self._interleave(cH, cV, cD)
        chunk_size = vec.size // self.total_bits
        seq0, seq1 = self._generate_sequences(chunk_size)

        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            offset = i * chunk_size
            chunk = vec[offset: offset + chunk_size]
            #chunk = vec[i:self.total_bits*chunk_size:self.total_bits]
            corr0, _ = pearsonr(chunk, seq0)
            corr1, _ = pearsonr(chunk, seq1)
            bit = int(corr1 > corr0)
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        
        return output
    
    def _try_decode(self, payload):
        try:
            return self.rscodec.decode(payload)
        except ReedSolomonError:
            rpayload = bytearray(b ^ 255 for b in payload)
            return self.rscodec.decode(rpayload)
    
    def extract(self, img):
        if img.ndim == 2:
            return self._try_decode(self._extract(img))
        elif img.ndim == 3:
            for i in range(img.shape[2]):
                try:
                    return self._try_decode(self._extract(img[:,:,i]))
                except ReedSolomonError:
                    pass
            return self._try_decode(self._extract(mean(img, 2)))
        else:
            raise TypeError("img must be a 2d or 3d array")
Ejemplo n.º 37
0
Archivo: all3.py Proyecto: KWMalik/tau
class Watermarker(object):
    EPSILON = 0.001
    def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"):
        self.mother = mother
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8

        rand = Random(seed)
        chunk_size = 50000
        self.seq0 = numpy.array([int(rand.random() > 0.7) for _ in range(chunk_size)])
        self.seq1 = numpy.array(self.seq0[::-1])
    
    def _interleave(self, cH, cV, cD):
        arr = numpy.zeros(cH.size + cV.size + cD.size)
        sources = [cH.reshape(cH.size), cV.reshape(cV.size), cD.reshape(cD.size)]
        for i in range(arr.size):
            src = sources[i % 3]
            j = i // 3
            if j >= src.size:
                arr = arr[:i]
                break
            arr[i] = src[j]
        return arr
    
    def _deinterleave(self, arr, cH, cV, cD):
        cH2 = numpy.zeros(cH.size)
        cV2 = numpy.zeros(cV.size)
        cD2 = numpy.zeros(cD.size)
        destinations = [cH2, cV2, cD2]
        for i in range(arr.size):
            destinations[i % 3][i // 3] = arr[i]
        return cH2.reshape(cH.shape), cV2.reshape(cV.shape), cD2.reshape(cD.shape)
    
    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        arr = self._interleave(cH, cV, cD)
        chunk_size = arr.size // self.total_bits
        sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size])
        
        for i, bit in enumerate(iterbits(payload)):
            seq = sequence_of[bit]
            arr[i * chunk_size: i * chunk_size + seq.size] += k * seq
        
        w, h = img.shape
        cH2, cV2, cD2 = self._deinterleave(arr, cH, cV, cD)
        return idwt2((cA, (cH2, cV2, cD2)), self.mother)[:w,:h]
    
    def embed(self, img, payload, k):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload))
        encoded = self.rscodec.encode(padded)
        
        if img.ndim == 2:
            return self._embed(img, encoded, k)
        elif img.ndim == 3:
            output = numpy.zeros(img.shape)
            for i in range(img.shape[2]):
                output[:,:,i] = self._embed(img[:,:,i], encoded, k)
            return output
        else:
            raise TypeError("img must be a 2d or 3d array")
    
    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        arr = self._interleave(cH, cV, cD)
        chunk_size = arr.size // self.total_bits
        seq0 = self.seq0[:chunk_size]
        seq1 = self.seq1[:chunk_size]

        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            chunk = arr[i * chunk_size: i * chunk_size + seq0.size]
            corr0, _ = pearsonr(chunk, seq0)
            corr1, _ = pearsonr(chunk, seq1)
            bit = int(corr1 > corr0)
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        return output
    
    def _try_decode(self, payload):
        try:
            out = self.rscodec.decode(payload)
        except ReedSolomonError:
            #print "!!", repr(payload)
            try:
                rpayload = bytearray(b ^ 255 for b in payload)
                out = self.rscodec.decode(rpayload)
            except ReedSolomonError:
                #print "!!", repr(rpayload)
                out = None
        return out
    
    def extract(self, img):
        if img.ndim == 2:
            return self._try_decode(self._extract(img))
        elif img.ndim == 3:
            for i in range(img.shape[2]):
                out = self._try_decode(self._extract(img[:,:,i]))
                if out is not None:
                    return out
            return self._try_decode(self._extract(mean(img, 2)))
        else:
            raise TypeError("img must be a 2d or 3d array")
def main():
    # read input args
    if len(sys.argv) != 3:
        print "usage: " + sys.argv[0] + " outer_size fps"
        return -1
    outer_size = int(sys.argv[1])
    fps = int(sys.argv[2])
    # delete old postit image
    old_postit_image = os.listdir('./datas/postit_saved/')
    for old_postit in old_postit_image:
        os.remove('./datas/postit_saved/' + old_postit)

    # memory save
    gc.enable()

    # set parameter
    analyse_config = yaml.load(open("./config/analyse_config.yaml", "r"))
    dist_thre = analyse_config["dist_thre"]
    angle_thre = analyse_config["angle_thre"]
    time_thre = analyse_config["time_thre"]
    video_save = False
    skip_mode = True

    # read movie file list
    movie_id = 0
    movie_files = os.listdir('./datas/movie/')
    if len(movie_files) == 0:
        print "no movie"
        return -1
    else:
        print "movie files:"
        for movie_file_each in movie_files:
            print movie_file_each

    # video reader and writer
    cap = cv2.VideoCapture('./datas/movie/' + movie_files[0])
    if video_save:
        writer = cv2.VideoWriter("./datas/movie/OUT.avi",
                                 cv2.cv.CV_FOURCC('M', 'J', 'P', 'G'), fps,
                                 (3840, 2160))
    # csv_file
    csv_every_second = open("./datas/csv/every_second.csv", "w")
    csv_final = open("./datas/csv/final.csv", "w")

    # reed solomon
    rs = RSCodec(14)

    # first select the desk area
    ret, frame = cap.read()
    window_name = "SELECT DESK"
    frame_for_select = cv2.resize(
        frame, (int(frame.shape[1] * 0.2), int(frame.shape[0] * 0.2)))
    print "Please select left-top and right-down"
    cv2.imshow(window_name, frame_for_select)
    desk_area = []
    cv2.setMouseCallback(window_name, mouse_callback, desk_area)
    cv2.waitKey(0)
    cv2.destroyWindow(window_name)
    desk_area = np.array(desk_area) * 5
    # select the mask area
    window_name = "SELECT left-top, right-top, right-down"
    print "Please select left-top and right-down"
    cv2.imshow(
        window_name, frame[desk_area[0][1]:desk_area[1][1],
                           desk_area[0][0]:desk_area[1][0]])
    postit_area = []
    cv2.setMouseCallback(window_name, mouse_callback, postit_area)
    cv2.waitKey(0)
    cv2.destroyWindow(window_name)
    postit_area_width = np.linalg.norm(
        np.array(postit_area[0]) - np.array(postit_area[1]))
    postit_area_height = np.linalg.norm(
        np.array(postit_area[1]) - np.array(postit_area[2]))

    # result file
    experiment_result = open("./datas/csv/resolution_result.csv", "w")
    experiment_result.write(str(desk_area) + "\n")

    # set desk by myself
    # desk_area = np.array([[1615, 890], [2110, 1285]])
    for movie_id in range(len(movie_files)):
        for resolution in range(0, 100):
            resolution = float(resolution) * 0.01
            print "pattern:" + str(resolution)
            time = 0
            success_count = 0
            postit_saved = {}
            cap = cv2.VideoCapture('./datas/movie/' + movie_files[movie_id])
            while (1):
                # read frame
                # print "progress: " + str(time)
                ret, frame = cap.read()
                if ret == False:
                    break
                    # movie_id += 1
                    # if movie_id < len(movie_files):
                    #      cap = cv2.VideoCapture('./movie/' + movie_files[movie_id])
                    #      ret, frame = cap.read()
                    # else:
                    #      break
                # save frame for final
                frame_for_final = np.copy(frame)

                # extract only desk area
                frame = frame[desk_area[0][1]:desk_area[1][1],
                              desk_area[0][0]:desk_area[1][0]]

                # change resolution
                frame = cv2.resize(frame,
                                   (int(frame.shape[1] * (1 - resolution)),
                                    int(frame.shape[0] * (1 - resolution))))
                frame_for_save = np.copy(frame)
                outer_size_resized = outer_size * ((1 - resolution)**2)

                # get postit
                getPostits = post_util.getPostits(frame, outer_size_resized)
                # postit_image_analyzing = getPostits.postit_image_analyzing
                postit_points = getPostits.postit_points
                recognized_location_rectangle = getPostits.recognized_location_rectangle
                # add buffer
                for i in range(0, len(postit_points)):
                    for j in range(0, len(postit_points[i])):
                        postit_points[i][j] += desk_area[0]

                # read postit's id and save
                postit_ids = []
                bit_array_list = []
                for i in range(0, len(postit_points)):
                    # postit_image_analyzing = cv2.imread("./postit_tmp_analyzing/" + str(i) + ".jpg")
                    postit_image_analyzing = np.load(
                        "./tmp_datas/postit_tmp_analyzing/" + str(i) + ".npy")
                    bit_array = post_util.readDots(
                        postit_image_analyzing).bit_array

                    bit_array_answer = []
                    for num in rs.encode([62]):
                        bit_array_answer.append(num)

                    bit_array_list.append(bit_array)
                    result_num = -1
                    try:
                        result_num = rs.decode(bit_array)[0]
                    except:
                        result_num = -1

                    # success check
                    # if (recognized_location_rectangle == 8) and bit_array_answer == bit_array:
                    #     success_count += 1
                    recognized_id_rectangle = 0
                    for each_bit in zip(bit_array_answer, bit_array):
                        if each_bit[0] == each_bit[1]:
                            recognized_id_rectangle += 1
                    success_count += recognized_id_rectangle + recognized_location_rectangle

                    postit_ids.append(result_num)
                    # save postit image
                    if result_num != -1:
                        # already exist
                        if postit_saved.has_key(result_num):
                            # judge move and rotate
                            # calc dist
                            dist = np.linalg.norm(
                                np.mean(postit_saved[result_num]
                                        ["points_saved"],
                                        axis=0) -
                                np.mean(postit_points[i], axis=0))
                            # calc angle(degree)
                            angle_vec_before = np.array(
                                postit_saved[result_num]["points_saved"][0]
                            ) - np.array(
                                postit_saved[result_num]["points_saved"][1])
                            angle_vec_after = np.array(
                                postit_points[i][0]) - np.array(
                                    postit_points[i][1])
                            vec_cos = np.dot(
                                angle_vec_before, angle_vec_after) / (
                                    np.linalg.norm(angle_vec_before) *
                                    np.linalg.norm(angle_vec_after))
                            angle = np.arccos(vec_cos) * 180 / np.pi
                            # add information
                            if dist > dist_thre:
                                if len(postit_saved[result_num]["move"]) == 0:
                                    postit_saved[result_num]["move"].append(
                                        time / fps)
                                elif (time / fps -
                                      postit_saved[result_num]["move"][-1]
                                      ) > 5:
                                    postit_saved[result_num]["move"].append(
                                        time / fps)
                            elif angle > angle_thre:
                                if len(postit_saved[result_num]
                                       ["rotate"]) == 0:
                                    postit_saved[result_num]["rotate"].append(
                                        time / fps)
                                elif (time / fps -
                                      postit_saved[result_num]["rotate"][-1]
                                      ) > 5:
                                    postit_saved[result_num]["rotate"].append(
                                        time / fps)
                            # renew
                            postit_saved[result_num]["points"] = postit_points[
                                i]
                            postit_saved[result_num][
                                "points_saved"] = postit_points[i]
                            postit_saved[result_num]["last_time"] = time / fps
                        # first appear
                        else:
                            postit_saved[result_num] = {
                                "points": postit_points[i],
                                "points_saved": postit_points[i],
                                "first_time": time / fps,
                                "last_time": time / fps,
                                "move": [],
                                "rotate": []
                            }
                            postit_image_for_save = cv2.imread(
                                "./tmp_datas/postit_tmp/" + str(i) + ".jpg")
                            cv2.imwrite(
                                "./datas/postit_saved/" + str(result_num) +
                                ".jpg", postit_image_for_save)

                # delete old postit(long time no see)
                for id, val in postit_saved.items():
                    if (time / fps - val["last_time"]) > time_thre:
                        postit_saved[id]["points"] = [[-5, 0], [0, 0], [0, -5],
                                                      [-5, -5]]

                # write csv
                csv_util.write_every_second(postit_saved, csv_every_second)
                # memory save
                del getPostits
                gc.collect()

                # key waiting
                key = cv2.waitKey(1)
                if key == 27:
                    break

                # when drawing dict info
                for key in postit_saved:
                    cv2.drawContours(
                        frame_for_final,
                        [np.array(postit_saved[key]["points"]).astype(np.int)],
                        0, (0, 0, 220), 2)
                    cv2.putText(frame_for_final, str(key),
                                (np.mean(postit_saved[key]["points"],
                                         axis=0).astype(np.int)[0] - 40,
                                 np.mean(postit_saved[key]["points"],
                                         axis=0).astype(np.int)[1]),
                                cv2.FONT_HERSHEY_PLAIN, 5.0, (0, 140, 0), 5)
                show_img_final = cv2.resize(
                    frame_for_final, (int(frame_for_final.shape[1] * 0.3),
                                      int(frame_for_final.shape[0] * 0.3)))
                cv2.imshow("show2", show_img_final)

                # add time
                time += 1

                if time > 23:
                    break

            # final save
            csv_util.write_final(postit_saved, csv_final)

            # print success rate
            experiment_result.write(
                str(int(postit_area_height * (1 - resolution))) + "," +
                str(int(postit_area_width * (1 - resolution))) + "," +
                str(time) + "," + str(success_count) + "," +
                str(float(success_count) / time) + "\n")
            cv2.imwrite("./datas/postit_saved/frame.jpg", frame_for_save)
            print "-----success result------"
            print "resolution:" + str(
                int(postit_area_height * (1 - resolution))) + "," + str(
                    int(postit_area_width * (1 - resolution)))
            print "success count: " + str(success_count)
            print "time:" + str(time)
            print "success rate: " + str(float(success_count) / time)
Ejemplo n.º 39
0
class Watermarker(object):
    def __init__(self, max_payload, ec_bytes, seed = 1895746671, mother = "bior3.1", sparsity = 0.7):
        self.mother = mother
        self.sparsity = sparsity
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8
        self.seed = seed
    
    @classmethod
    def _interleave(cls, cH, cV, cD):
        vec = numpy.zeros(cH.size + cV.size + cD.size, dtype = float)
        vec[0::3] = cH.ravel()
        vec[1::3] = cV.ravel()
        vec[2::3] = cD.ravel()
        return vec
    
    @classmethod
    def _deinterleave(cls, vec, cH, cV, cD):
        return vec[0::3].reshape(cH.shape), vec[1::3].reshape(cV.shape), vec[2::3].reshape(cD.shape)
    
    def _generate_sequences(self, chunk_size):
        rand = Random(self.seed)
        seq0 = numpy.array([int(rand.random() >= self.sparsity) for _ in range(chunk_size)])
        seq1 = seq0[::-1]
        return seq0, seq1
    
    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother)
        vec = self._interleave(cH, cV, cD)
        chunk_size = vec.size // self.total_bits
        sequences = self._generate_sequences(chunk_size)
        
        for i, bit in enumerate(iterbits(payload)):
            offset = i * chunk_size
            vec[offset : offset + chunk_size] += k * sequences[bit]
            #vec[i : self.total_bits*chunk_size : self.total_bits] += k * sequences[bit]
        
        w, h = img.shape
        cH2, cV2, cD2 = self._deinterleave(vec, cH, cV, cD)
        return idwt2((cA, (cH2, cV2, cD2)), self.mother)[:w,:h]
    
    def embed(self, img, payload, k = 4, rescale_color = True):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload))
        encoded = self.rscodec.encode(padded)
        
        if img.ndim == 2:
            output = self._embed(img, encoded, k)
        elif img.ndim == 3:
            output = numpy.zeros(img.shape, dtype=float)
            for i in range(img.shape[2]):
                output[:,:,i] = self._embed(img[:,:,i], encoded, k)
        else:
            raise TypeError("img must be a 2d or 3d array")
        
        if rescale_color:
            output = rescale_intensity(output, out_range = (numpy.min(img), numpy.max(img)))
        return output
    
    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img.astype(float), self.mother)
        vec = self._interleave(cH, cV, cD)
        chunk_size = vec.size // self.total_bits
        seq0, seq1 = self._generate_sequences(chunk_size)

        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            offset = i * chunk_size
            chunk = vec[offset: offset + chunk_size]
            #chunk = vec[i:self.total_bits*chunk_size:self.total_bits]
            corr0, _ = pearsonr(chunk, seq0)
            corr1, _ = pearsonr(chunk, seq1)
            bit = int(corr1 > corr0)
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        
        return output
    
    def _try_decode(self, payload):
        try:
            return self.rscodec.decode(payload)
        except ReedSolomonError:
            rpayload = bytearray(b ^ 255 for b in payload)
            return self.rscodec.decode(rpayload)
    
    def extract(self, img):
        if img.ndim == 2:
            return self._try_decode(self._extract(img))
        elif img.ndim == 3:
            for i in range(img.shape[2]):
                try:
                    return self._try_decode(self._extract(img[:,:,i]))
                except ReedSolomonError:
                    pass
            return self._try_decode(self._extract(mean(img, 2)))
        else:
            raise TypeError("img must be a 2d or 3d array")
Ejemplo n.º 40
0
Archivo: all.py Proyecto: KWMalik/tau
class Watermarker(object):
    EPSILON = 0.001
    def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"):
        self.mother = mother
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8

        rand = Random(seed)
        chunk_size = 50000
        self.seq0 = numpy.array([int(rand.random() > 0.7) for _ in range(chunk_size)])
        self.seq1 = numpy.array(self.seq0[::-1])
        #while True:
        #    self.seq0 = numpy.array([int(rand.random() > 0.8) for _ in range(chunk_size)])
        #    self.seq1 = numpy.array([int(rand.random() > 0.75) for _ in range(chunk_size)])
        #    corr, _ = pearsonr(self.seq0, self.seq1)
        #    if corr < self.EPSILON:
        #        break
    
    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        cH2 = cH.reshape(cH.size)
        cV2 = cV.reshape(cV.size)
        cD2 = cD.reshape(cD.size)
        assert cH2.shape == cV2.shape == cD2.shape
        chunk_size = (cH2.size * 3) // (self.total_bits)
        sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size])
        buffers = (cH2, cV2, cD2)
        
        for i, bit in enumerate(iterbits(payload)):
            seq = sequence_of[bit]
            target = buffers[i % 3]
            offset = (i//3) * chunk_size
            target[offset:offset + seq.size] += k * seq
        w, h = img.shape
        return idwt2((cA, (cH2.reshape(cH.shape), cV2.reshape(cV.shape), cD2.reshape(cD.shape))), self.mother)[:w,:h]
    
    def embed(self, img, payload, k):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        padded = bytearray(payload) + b"\x00" * (self.max_payload - len(payload))
        encoded = self.rscodec.encode(padded)
        
        if len(img.shape) == 2:
            return self._embed(img, encoded, k)
        elif len(img.shape) == 3:
            output = numpy.zeros(img.shape)
            for i in range(img.shape[2]):
                output[:,:,i] = self._embed(img[:,:,i], encoded, k)
            return output
        else:
            raise TypeError("img must be a 2d or 3d array")
    
    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        cH2 = cH.reshape(cH.size)
        cV2 = cV.reshape(cV.size)
        cD2 = cD.reshape(cD.size)
        assert cH2.shape == cV2.shape == cD2.shape
        buffers = (cH2, cV2, cD2)
        chunk_size = (cH2.size * 3) // (self.total_bits)
        seq0 = self.seq0[:chunk_size]
        seq1 = self.seq1[:chunk_size]

        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            target = buffers[i % 3]
            offset = (i//3) * chunk_size
            chunk = target[offset : offset + seq0.size]
            corr0, _ = pearsonr(chunk, seq0)
            corr1, _ = pearsonr(chunk, seq1)
            bit = int(corr1 > corr0)
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        #print repr(output)
        return output
    
    def extract(self, img):
        if len(img.shape) == 2:
            return self.rscodec.decode(self._extract(img))
        elif len(img.shape) == 3:
            for i in range(img.shape[2]):
                try:
                    return self.rscodec.decode(self._extract(img[:,:,i]))
                except ReedSolomonError:
                    pass
            return self.rscodec.decode(self._extract(mean(img, 2)))
        else:
            raise TypeError("img must be a 2d or 3d array")
Ejemplo n.º 41
0
class Watermarker(object):
    def __init__(self, msg_bytes, ec_bytes, seed, mother = "haar"):
        self.mother = mother
        self.rscodec = RSCodec(ec_bytes)
        self.msg_bytes = msg_bytes
        self.total_bits = (msg_bytes + ec_bytes) * 8

        rand = Random(seed)
        #self.mask = [rand.randint(0,255) for _ in range(msg_bytes + ec_bytes)]
        self.mask = [0] * (msg_bytes + ec_bytes)
        chunk_size = 256*512 // self.total_bits
        espilon = 0.0001
        while True:
            self.seq0 = numpy.array([int(rand.random() > 0.75) for _ in range(chunk_size)])
            self.seq1 = numpy.array([int(rand.random() > 0.7) for _ in range(chunk_size)])
            corr, _ = pearsonr(self.seq0, self.seq1)
            if abs(corr) < espilon:
                break
    
    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        w, h = cH.shape
        cH2 = cH.reshape(cH.size)
        cV2 = cV.reshape(cV.size)
        chunk_size = cH2.size // (self.total_bits // 2)
        assert chunk_size >= self.seq0.size
        
        for i, bit in enumerate(iterbits(payload)):
            dst = (cH2, cV2)[i % 2]
            seq = (self.seq0, self.seq1)[bit]
            dst[(i//2)*chunk_size:(i//2)*chunk_size + seq.size] += k * seq
        return idwt2((cA, (cH2.reshape(w, h), cV2.reshape(w, h), cD)), self.mother)[:img.shape[0],:img.shape[1]]
    
    def embed(self, img, payload, k = 10):
        if len(payload) > self.msg_bytes:
            raise ValueError("payload too long")
        if isinstance(payload, str):
            payload = bytearray(payload)
        payload.extend([0] * (self.msg_bytes - len(payload)))
        encoded = self.rscodec.encode(payload)
        masked = [v ^ m for v, m in zip(encoded, self.mask)]

        if len(img.shape) == 2:
            return self._embed(img, masked, k)
        elif len(img.shape) == 3:
            res = numpy.zeros(img.shape)
            for i in range(img.shape[2]):
                layer = self._embed(img[:,:,i], masked, k)
                res[:,:,i] = layer
            return res
        else:
            raise TypeError("image must be a 2d or 3d array")

    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        w, h = cH.shape
        cH2 = cH.reshape(cH.size)
        cV2 = cV.reshape(cV.size)
        chunk_size = cH2.size // (self.total_bits // 2)
        
        maskiter = iter(self.mask)
        payload = bytearray()
        byte = 0
        for i in range(self.total_bits):
            src = (cH2, cV2)[i % 2]
            chunk = src[(i//2)*chunk_size:(i//2)*chunk_size + self.seq0.size]
            corr0, _ = pearsonr(chunk, self.seq0)
            corr1, _ = pearsonr(chunk, self.seq1)
            bit = int(corr1 > corr0)
            byte = bit | (byte << 1)
            if i % 8 == 7:
                payload.append(byte ^ maskiter.next())
                byte = 0
        print repr(payload)
        return self.rscodec.decode(payload)

    def extract(self, img):
        if len(img.shape) == 2:
            return self._extract(img)
        elif len(img.shape) == 3:
            for i in range(img.shape[2]):
                try:
                    return self._extract(img[:,:,i])
                except ReedSolomonError:
                    pass
            return self._extract(mean(img, 2))
        else:
            raise TypeError("image must be a 2d or 3d array")
Ejemplo n.º 42
0
 def test_simple(self):
     rs = RSCodec(10)
     msg = bytearray("hello world " * 10, "utf8")
     enc = rs.encode(msg)
     dec = rs.decode(enc)
     self.assertEqual(dec, msg)
Ejemplo n.º 43
0
class Watermarker(object):
    EPSILON = 0.001
    def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"):
        self.mother = mother
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8
        self.seed = seed

    def _embed(self, img, payload, k):
        rand = Random(self.seed)
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        cD2 = cD.reshape(cD.size)
        for bit in iterbits(payload):
            seq = numpy.array([int(rand.random() > 0.95) for _ in range(cD2.size)]) 
            if bit:
                cD2 += k * seq
        return idwt2((cA, (cH, cV, cD2.reshape(cD.shape))), self.mother)[:img.shape[0],:img.shape[1]]
    
    def embed(self, img, payload, k):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        payload = bytearray(payload) + "\x00" * (self.max_payload - len(payload))
        encoded = self.rscodec.encode(payload)
        
        if len(img.shape) == 2:
            return self._embed(img, encoded, k)
        elif len(img.shape) == 3:
            output = numpy.zeros(img.shape)
            for i in range(img.shape[2]):
                output[:,:,i] = self._embed(img[:,:,i], encoded, k)
            return output
        else:
            raise TypeError("img must be a 2d or 3d array")
    
    def _extract(self, img):
        rand = Random(self.seed)
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        cD2 = cD.reshape(cD.size)
        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            seq = numpy.array([int(rand.random() > 0.95) for _ in range(cD2.size)]) 
            corr, _ = pearsonr(cD2, seq)
            bit = int(corr > 0.1)
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        print repr(output)
        return output
    
    def extract(self, img):
        if len(img.shape) == 2:
            return self.rscodec.decode(self._extract(img))
        elif len(img.shape) == 3:
            for i in range(img.shape[2]):
                try:
                    return self.rscodec.decode(self._extract(img[:,:,i]))
                except ReedSolomonError:
                    pass
            return self.rscodec.decode(self._extract(mean(img, 2)))
        else:
            raise TypeError("img must be a 2d or 3d array")
Ejemplo n.º 44
0
class Watermarker(object):
    EPSILON = 0.001
    def __init__(self, max_payload, ec_bytes, seed = 1910819922, mother = "haar"):
        self.mother = mother
        self.rscodec = RSCodec(ec_bytes)
        self.max_payload = max_payload
        self.total_bits = (max_payload + ec_bytes) * 8

        rand = Random(seed)
        chunk_size = 3000
        while True:
            self.seq0 = numpy.array([int(rand.random() > 0.8) for _ in range(chunk_size)])
            self.seq1 = numpy.array([int(rand.random() > 0.75) for _ in range(chunk_size)])
            corr, _ = pearsonr(self.seq0, self.seq1)
            if corr < self.EPSILON:
                break
    
    def _embed(self, img, payload, k):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        target = cD.reshape(cD.size)
        chunk_size = target.size // self.total_bits
        sequence_of = (self.seq0[:chunk_size], self.seq1[:chunk_size])
        
        for i, bit in enumerate(iterbits(payload)):
            seq = sequence_of[bit]
            #chunk = target[i::self.total_bits][:seq.size]
            chunk = target[i * chunk_size:i * chunk_size + seq.size]
            chunk += k * seq
        return idwt2((cA, (cH, cV, target.reshape(cH.shape))), self.mother)[:img.shape[0],:img.shape[1]]
    
    def embed(self, img, payload, k):
        if len(payload) > self.max_payload:
            raise ValueError("payload too long")
        payload = bytearray(payload) + "\x00" * (self.max_payload - len(payload))
        encoded = self.rscodec.encode(payload)
        
        if len(img.shape) == 2:
            return self._embed(img, encoded, k)
        elif len(img.shape) == 3:
            hsv = rgb2hsv(img)
            i = 0
            hsv[:,:,i] = self._embed(hsv[:,:,i], encoded, k)
            return hsv2rgb(hsv)
        else:
            raise TypeError("img must be a 2d or 3d array")
    
    def _extract(self, img):
        cA, (cH, cV, cD) = dwt2(img, self.mother)
        target = cD.reshape(cD.size)
        chunk_size = target.size // self.total_bits
        seq0 = self.seq0[:chunk_size]
        seq1 = self.seq1[:chunk_size]

        byte = 0
        output = bytearray()
        for i in range(self.total_bits):
            chunk = target[i * chunk_size : (i * chunk_size) + seq0.size]
            #chunk = target[i::self.total_bits][:seq0.size]
            #if not all(chunk[i] == chunk[i+1] for i in range(chunk.size-1)):
            corr0, _ = pearsonr(chunk, seq0)
            corr1, _ = pearsonr(chunk, seq1)
            bit = int(corr1 > corr0)
            #else:
            #    bit = 0
            byte = (byte << 1) | bit
            if i % 8 == 7:
                output.append(byte)
                byte = 0
        print repr(output)
        return output
    
    def extract(self, img):
        if len(img.shape) == 2:
            return self.rscodec.decode(self._extract(img))
        elif len(img.shape) == 3:
            hsv = rgb2hsv(img)
            return self.rscodec.decode(self._extract(hsv[:,:,0]))
        else:
            raise TypeError("img must be a 2d or 3d array")